package com.apes.fn.server.workOrder.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.business.fixedLoss.modle.LossQuotation;
import com.apes.fn.business.fixedLoss.repository.LossQuotationRepository;
import com.apes.fn.business.fixedLoss.service.LossQuotationService;
import com.apes.fn.crm.customerExpand.FnCustomerExpand;
import com.apes.fn.crm.customerExpand.FnCustomerExpandRepository;
import com.apes.fn.mdm.paint.PaintBusinessScope;
import com.apes.fn.scm.commodityInquiry.model.ExternalInquiry;
import com.apes.fn.scm.commodityInquiry.model.ExternalInquiryItem;
import com.apes.fn.scm.commodityInquiry.repository.ExternalInquiryItemRepository;
import com.apes.fn.scm.commodityInquiry.repository.ExternalInquiryRepository;
import com.apes.fn.scm.retailOrder.service.tc.TCService;
import com.apes.fn.server.pickUpCar.model.PickUpCar;
import com.apes.fn.server.pickUpCar.repository.PickUpCarRepository;
import com.apes.fn.server.servicePlan.model.ServicePlan;
import com.apes.fn.server.servicePlan.model.ServicePlanItem;
import com.apes.fn.server.servicePlan.repository.ServicePlanDao;
import com.apes.fn.server.servicePlan.repository.ServicePlanItemRepository;
import com.apes.fn.server.servicePlan.repository.ServicePlanRepository;
import com.apes.fn.server.servicePlan.service.ConditionBuilder;
import com.apes.fn.server.servicePlan.service.ServicePlanceService;
import com.apes.fn.server.servicePlan.service.ServiceToForeign;
import com.apes.fn.server.transferVehicle.model.InnerPickDeliveryUpCar;
import com.apes.fn.server.transferVehicle.repository.InnerPickDeliveryUpCarRepository;
import com.apes.fn.server.workOrder.model.ConstructionRecord;
import com.apes.fn.server.workOrder.model.MaintenanceOrder;
import com.apes.fn.server.workOrder.repository.ConstructRecordRepository;
import com.apes.fn.server.workOrder.repository.MaintenanceOrderRepository;
import com.apes.fn.server.workOrder.service.MaintenanceOrderProcess.MaintenanceOrderOutWorkService;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.event.Listener;
import com.apes.framework.plugin.mq.MQUtil;
import com.apes.framework.plugin.mq.annotation.Consumer;
import com.apes.framework.plugin.outbox.OutboxEventService;
import com.apes.framework.plugin.outbox.OutboxPayloadWrapper;
import com.apes.framework.plugin.outbox.annotation.OutboxSubscriber;
import com.apes.framework.plugin.soe.metadata.BusinessAttributeValue;
import com.apes.framework.plugin.soe.store.database.repository.BusinessAttributeValueRepository;
import com.apes.framework.util.*;
import com.apes.pi.service.PiManager;
import com.apes.scm.contract.model.Contract;
import com.apes.scm.contract.repository.ContractRepository;
import com.apes.scm.masterdata.car.model.CarServiceLevel;
import com.apes.scm.masterdata.car.service.CarServiceLevelService;
import com.apes.scm.masterdata.enumeration.model.Enumeration;
import com.apes.scm.masterdata.enumeration.repository.EnumerationRepository;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.frame.model.Store;
import com.apes.scm.masterdata.frame.repository.DeptRepository;
import com.apes.scm.masterdata.frame.repository.StoreRepository;
import com.apes.scm.masterdata.frame.service.StoreService;
import com.apes.scm.masterdata.party.model.Party;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.AccessProviderRepository;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.masterdata.party.service.PartyRoleService;
import com.apes.scm.masterdata.product.model.Product;
import com.apes.scm.masterdata.product.model.ServeType;
import com.apes.scm.masterdata.product.repository.ProductRepository;
import com.apes.scm.masterdata.stock.model.Location;
import com.apes.scm.masterdata.stock.service.LocationService;
import com.apes.scm.rbac.model.User;
import com.apes.scm.rbac.repository.UserRepository;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.stream.Collectors.groupingBy;

/**
 * Creator: zouyc
 * CreateDate: 2020-04-15 18:59
 * Description:
 **/
@Service("maintenanceOrderService")
public class MaintenanceOrderService extends DomainService {
    @Autowired
    private MaintenanceOrderRepository maintenanceOrderRepository;
    @Autowired
    private ServicePlanRepository servicePlanRepository;
    @Autowired
    private ServicePlanItemRepository servicePlanItemRepository;
    @Autowired
    private ConstructionRecordService constructionRecordService;
    @Autowired
    private ServicePlanceService servicePlanceService;
    @Autowired
    private ServiceToForeign serviceToForeign;
    @Autowired
    private PiManager piManager;
    @Autowired
    private ServicePlanDao servicePlanDao;
    @Autowired
    private PartyRoleRepository partyRoleRepository;
    @Autowired
    private BusinessAttributeValueRepository businessAttributeValueRepository;
    @Autowired
    private EnumerationRepository enumerationRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private StoreRepository storeRepository;
    @Autowired
    private MaintenanceOrderOutWorkService maintenanceOrderOutWorkService;
    
    public Map bindPartsToWork(SimpleRequest simpleRequest){
        MaintenanceOrder originMaintenanceOrder = simpleRequest.getO(MaintenanceOrder.class);
        MaintenanceOrder maintenanceOrder = maintenanceOrderRepository.findOne(originMaintenanceOrder.getId());
        if(maintenanceOrder == null) throw new RuntimeException("工单不存在");
        maintenanceOrder.setParts(originMaintenanceOrder.getParts());
        maintenanceOrder.setOperator1(originMaintenanceOrder.getOperator1());
        maintenanceOrder.setWorker(originMaintenanceOrder.getWorker());
        bindPartsToWorkInner(maintenanceOrder);
        return MapUtil.mapper("success",true);
    }
    public Object findOne(SimpleRequest request){
        JSONObject jo = request.getJO();
        String id = jo.getString("id");
        MaintenanceOrder maintenanceOrder = maintenanceOrderRepository.findOne(id);
        MaintenanceOrder out = maintenanceOrderRepository.findOne(JpaDsl.toCriteria("businessType", "EQ", "out", "servicePlanItem.id", "EQ", maintenanceOrder.getServicePlanItem().getId())).orElse(null);
        assert out != null;
        Map mapper = MapUtil.mapper("SERVICE_PLAN_ID", out.getServicePlanId(), "STATE", out.getState(), "businessKey", out.getId());
        return this.invoke("fn.maintenance.findOutMaintenanceOrder",mapper);
    }

    /**
     * 绑定配件
     * @param maintenanceOrder
     * @return
     */
    public void bindPartsToWorkInner(MaintenanceOrder maintenanceOrder){
        String maintenanceOrderId = maintenanceOrder.getId(); //关联的工单号
        List<ServicePlanItem> servicePlanItemList = maintenanceOrder.getParts();
        List<ServicePlanItem> resultServicePlanItemList = new ArrayList<>();

        ServicePlanItem sourcePlanItem = maintenanceOrder.getServicePlanItem();
        ServicePlan sourcePlan = sourcePlanItem.getServicePlan();

        servicePlanItemList.forEach(item ->{
            ServicePlanItem servicePlanItem = servicePlanItemRepository.findOne(item.getId());
            if(servicePlanItem == null) throw new RuntimeException("配件明细行不存在，编码：" + item.getId());
            resultServicePlanItemList.add(servicePlanItem);
        });
        Map groupMap = resultServicePlanItemList.stream().collect(groupingBy((servicePlanItem)->{
            return servicePlanItem.getServicePlan().getId();
        }));
        AtomicBoolean crossOrderMark = new AtomicBoolean(false);

        groupMap.forEach((k,v)->{
            List<ServicePlanItem> servicePlanItems =
                    new ArrayList<ServicePlanItem>((Collection<? extends ServicePlanItem>) v);
            ServicePlan servicePlan = servicePlanItems.stream().findFirst().get().getServicePlan();
            String id = servicePlan.getId();
            servicePlan.getServicePlanItems().forEach(servicePlanItem -> {
                servicePlanItems.stream().forEach(servicePlanItem1 -> {
                    if(servicePlanItem.getId().equals(servicePlanItem1.getId())){
                        if (!id.equals(sourcePlan.getId())) crossOrderMark.set(true);
                        servicePlanItem.setRelevanceWorkOrder(maintenanceOrderId);
                    }
                });
            });
            if (crossOrderMark.get()){
                servicePlan.getServicePlanItems().forEach(servicePlanItem -> {
                    servicePlanItems.stream().forEach(servicePlanItem1 -> {
                        if(servicePlanItem.getId().equals(servicePlanItem1.getId())){
                            servicePlanItem.setCrossOrderWorkMark("1");
                        }
                    });
                });
            }
            servicePlan = servicePlanceService.updateOnly(servicePlan);
        });
        //方案明细增加跨单标记
        if (crossOrderMark.get()){
            sourcePlanItem.setCrossOrderWorkMark("1");
            servicePlanItemRepository.saveAndFlush(sourcePlanItem);
        }
    }

    public Map bpConstruction(SimpleRequest simpleRequest){
        JSONArray ja = simpleRequest.getJA();
        //完成施工的明细
        List<MaintenanceOrder> finishItems = new ArrayList<>();
        for (Object o : ja) {
            JSONObject jo = (JSONObject) o;
            MaintenanceOrder maintenanceOrder = bpConstructionInner(jo);
            finishItems.add(maintenanceOrder);
        }

        bpFinishCallBackServicePlanData(finishItems);

        return MapUtil.mapper("success",true);
    }

    private void bpFinishCallBackServicePlanData(List<MaintenanceOrder> finishItems) {
        //获取源方案工单
        finishItems.addAll(finishItems.stream().filter(Objects::nonNull).distinct().map(this::findOrigin).collect(Collectors.toList()));
        //所有工单统一处理
        Map<String, List<MaintenanceOrder>> planItems = finishItems.stream()
                .filter(Objects::nonNull)
                .distinct()
                .collect(groupingBy(m -> m.getServicePlanItem().getServicePlan().getId()));
        Iterator<String> iterator = planItems.keySet().iterator();

        while (iterator.hasNext()) {
            String planId = iterator.next();
            List<MaintenanceOrder> maintenanceOrderList = planItems.get(planId);
            ServicePlan servicePlan = servicePlanRepository.findOne(planId);
            String state = "treatQuality";
            //更新对应方案明细，设置完成状态
            for (MaintenanceOrder maintenanceOrder : maintenanceOrderList) {
                for (ServicePlanItem servicePlanItem : servicePlan.getServicePlanItems()) {
                    if (maintenanceOrder.getServicePlanItem().getId().equals(servicePlanItem.getId())){
                        servicePlanItem.setFinishDate(new Date());
                        if (!Objects.isNull(servicePlanItem.getParentServicePlanItem())){
                            servicePlanItem.getParentServicePlanItem().setWorkState(state);
                        }
                        servicePlanItem.setWorkState(state);
                    }
                }
            }

            // 检查是否整单完成
            if("finish".equals(servicePlan.checkResultByItem())){
                servicePlan.setFinishWork(true);
            };
            servicePlanceService.updateOnly(servicePlan);
            servicePlanceService.confirmToApp(servicePlan);
            //回写工单明细
//            maintenanceOrderList.forEach(this::onlyReWriteBackServicePlanItemsFinishData);
            //回写方案明细

            //回写方案
//            onlyReWriteBackServicePlanFinishData(servicePlan);
        }
    }


    /**
     * 钣喷完工调用
     * @param
     * @return
     */
    private MaintenanceOrder bpConstructionInner(JSONObject jo){
        PartyRole role = partyRoleRepository.findOne(jo.getJSONObject("operator").getString("id"));
        Date startDate = jo.getDate("beginTime");
        Date endDate = jo.getDate("endTime");
        JSONObject workItems = jo.getJSONObject("workItems");

        MaintenanceOrder maintenanceOrder = maintenanceOrderRepository.findOne(jo.getString("id"));
        if(maintenanceOrder == null) throw new RuntimeException("无效工单号");
        if(maintenanceOrder.getFinishDate() != null) return null;

        if("out".equals(maintenanceOrder.getBusinessType())){
            throw new RuntimeException(maintenanceOrder.getProduct().getName() + "是外协商品，请在PC端外协工单界面完工");
        }

        ServicePlanItem servicePlanItem = maintenanceOrder.getServicePlanItem();
        if(servicePlanItem.isPaintFlag()) throw new RuntimeException("带安商品需要转外协完工");
        checkPaintBusinessPrice(maintenanceOrder);
        if(maintenanceOrder.getFinishDate() == null){//完成施工
            //检测是否处于施工中
            if(!MaintenanceOrder.WORK_ORDER_WORKSTATE_WAIT.equals(maintenanceOrder.getWorkState())) throw new RuntimeException("该工单不处于新增状态中，无法完成");
            maintenanceOrder.setOperator1(role);
            maintenanceOrder.setWorker1(tranferWorkByArray(workItems.getJSONArray("worker1")));
            maintenanceOrder.setWorker2(tranferWorkByArray(workItems.getJSONArray("worker2")));
            maintenanceOrder.setWorker3(tranferWorkByArray(workItems.getJSONArray("worker3")));
            maintenanceOrder.setWorker4(tranferWorkByArray(workItems.getJSONArray("worker4")));

            maintenanceOrder.setWorker1Show(maintenanceOrder.changeWorkerToWorkerShow(maintenanceOrder.getWorker1()));
            maintenanceOrder.setWorker2Show(maintenanceOrder.changeWorkerToWorkerShow(maintenanceOrder.getWorker2()));
            maintenanceOrder.setWorker3Show(maintenanceOrder.changeWorkerToWorkerShow(maintenanceOrder.getWorker3()));
            maintenanceOrder.setWorker4Show(maintenanceOrder.changeWorkerToWorkerShow(maintenanceOrder.getWorker4()));

            maintenanceOrder.setState(MaintenanceOrder.CONST_TABLE_STATE_FINISH);
            maintenanceOrder.setWorkState(MaintenanceOrder.WORK_ORDER_WORKSTATE_FINISH);
            maintenanceOrder.setFinishUid(role);
            maintenanceOrder.setFinishDate(new Date());
            constructionRecordService.constructionRecordForBP(maintenanceOrder,startDate,endDate);
            onlyReWriteBackData(maintenanceOrder,"finish");


        }else{ //只修改施工人
            maintenanceOrder.setWorker1(tranferWorkByArray(workItems.getJSONArray("worker1")));
            maintenanceOrder.setWorker2(tranferWorkByArray(workItems.getJSONArray("worker2")));
            maintenanceOrder.setWorker3(tranferWorkByArray(workItems.getJSONArray("worker3")));
            maintenanceOrder.setWorker4(tranferWorkByArray(workItems.getJSONArray("worker4")));
            maintenanceOrder.setWorker1Show(maintenanceOrder.changeWorkerToWorkerShow(maintenanceOrder.getWorker1()));
            maintenanceOrder.setWorker2Show(maintenanceOrder.changeWorkerToWorkerShow(maintenanceOrder.getWorker2()));
            maintenanceOrder.setWorker3Show(maintenanceOrder.changeWorkerToWorkerShow(maintenanceOrder.getWorker3()));
            maintenanceOrder.setWorker4Show(maintenanceOrder.changeWorkerToWorkerShow(maintenanceOrder.getWorker4()));
            maintenanceOrderRepository.saveAndFlush(maintenanceOrder);
        }
        ServicePlan servicePlan = maintenanceOrder.getServicePlanItem().getServicePlan();
        if (maintenanceOrderRepository.findWorkindByServicePlan(servicePlan.getId()).size()==1) {
            servicePlanceService.addServicePlanLogger(servicePlan,"开始施工","");
        }
        return maintenanceOrder;
    }

    /**
     * 判断油漆采购价格
     */
    private void checkPaintBusinessPrice(MaintenanceOrder maintenanceOrder){
        Store store = storeRepository.findByDept(maintenanceOrder.getBelongDept());
        //如果不是钣喷基地不需要判断范围和价格
        if ("S0106".equals(maintenanceOrder.getProduct().getClassify().getId().substring(0, 5)) && "钣喷基地".equals(store.getStoreType().getDescription())) {
            //检查油漆采购范围和价格
            List<PaintBusinessScope> paintBusinessScope = invoke("fn.paintScope.checkPaintBusinessScope", MapUtil.mapper(
                    "deptId", maintenanceOrder.getBelongDept().getId(),
                    "classifyId", maintenanceOrder.getProduct().getClassify().getId()
            ));

            JSONObject paintBusinessPrice = invoke("fn.paintScope.checkPaintBusinessPrice", MapUtil.mapper(
                    "productId", maintenanceOrder.getProduct().getId(),
                    "companyId", maintenanceOrder.getBelongDept().getCompany().getId(),
                    "supplierId", maintenanceOrder.getServicePlanItem().getSupplier() == null ? null : maintenanceOrder.getServicePlanItem().getSupplier().getId()
            ));
            PaintBusinessScope paintBusinessScope1 = paintBusinessScope.get(0);
            if (paintBusinessScope1.getPaintType().equals("water")) {
                if (paintBusinessPrice.getDouble("Q001") == 0) throw new RuntimeException("请联系采购中心定义油漆采购价格");
            } else {
                if (paintBusinessPrice.getDouble("Q002") == 0) throw new RuntimeException("请联系采购中心定义油漆采购价格");
            }

            if (!paintBusinessPrice.containsKey("Q004") || !paintBusinessPrice.containsKey("Q003") || !paintBusinessPrice.containsKey("Q001") || !paintBusinessPrice.containsKey("Q002")) {
                throw new RuntimeException("未定义油漆相关价格策略，联系采购人员定义，商品编码为：" + maintenanceOrder.getProduct().getId());
            }
            if (paintBusinessPrice.getDouble("Q004") < 0.001d || paintBusinessPrice.getDouble("Q003") < 0.001d) {
                throw new RuntimeException("油漆分销价格为 0，联系采购人员定义，商品编码为：" + maintenanceOrder.getProduct().getId());
            }

            if (paintBusinessPrice.getDouble("Q001") < 0.001d || paintBusinessPrice.getDouble("Q002") < 0.001d) {
                throw new RuntimeException("油漆采购价格为 0，联系采购人员定义，商品编码为：" + maintenanceOrder.getProduct().getId());
            }

        }

    }


    /**
     * 根据工单返回当前耗时
     * @param maintenanceOrder
     * @return
     */
    public int calculateTimeByMaintenanceOrder(MaintenanceOrder maintenanceOrder){
        int resultHour = constructionRecordService.caculateTimeByMaintenanceOrder(maintenanceOrder);
        if(MaintenanceOrder.WORK_ORDER_WORKSTATE_WORKING.equals(maintenanceOrder.getWorkState())){
            List<String> list = new ArrayList<>();
            list.add("start");
            list.add("renew");
            List<ConstructionRecord> constructionRecords = SpringManager.getBean(ConstructRecordRepository.class).findConstructionRecordForCalculate(maintenanceOrder.getId(),list);
            resultHour = resultHour + (int)((new Date().getTime() - constructionRecords.stream().findFirst().get().getCreateDate().getTime()) / 1000);
        }
        return resultHour;
    }



    /**
     *平台转换
     * @param simpleRequest
     * @return
     */
    public Map chanceWorkPlatform(SimpleRequest simpleRequest){
        JSONArray array = simpleRequest.getJA();
        array.stream().forEach(item ->{
            JSONObject tempJosn =(JSONObject)item;
            String id = tempJosn.getString("id");
            String originStyle = tempJosn.getString("originStyle");
            String changeStyle = tempJosn.getString("changeStyle");
            PartyRole role = partyRoleRepository.findOne(tempJosn.getString("operator"));
            if("cosmetology".equals(changeStyle) || "machineRepa".equals(changeStyle)
                    || "sprayPaint".equals(changeStyle) || "other".equals(changeStyle)){
                MaintenanceOrder maintenanceOrder = maintenanceOrderRepository.findOne(id);
                if(maintenanceOrder == null) throw new RuntimeException("工单不存在，请检查入参，工单号：" + id);

                //钣喷S0105工时可以移
                if("sprayPaint".equals(changeStyle) && !maintenanceOrder.getProduct().getClassify().getId().startsWith("S0105")){
                    throw new RuntimeException("只有品类【S0105】可以转入钣喷，商品名称" + maintenanceOrder.getProduct().getName());
                }
                maintenanceOrder.setWorkPlatform(changeStyle);
                maintenanceOrderRepository.saveAndFlush(maintenanceOrder);
            }else{
                throw new RuntimeException("传参错误，转换类型不存在，错误类型：" + changeStyle);
            }
        });

        return MapUtil.mapper("success",true);
    }

    /**
     * 完工处理方案
     * @param maintenanceOrder
     */
    private ServicePlan commonFinishServicePlan(MaintenanceOrder maintenanceOrder) {
        //更新对应方案明细，设置完成状态
        ServicePlanItem servicePlanItem = maintenanceOrder.getServicePlanItem();
        servicePlanItem.setFinishDate(new Date());
        servicePlanItemRepository.saveAndFlush(servicePlanItem);

        // 检查是否整单完成
        ServicePlan servicePlan =servicePlanItem.getServicePlan();
        servicePlanItemWorkState(maintenanceOrder,servicePlan,"treatQuality",false);
        if("finish".equals(servicePlan.checkResultByItem())){
            servicePlan.setFinishWork(true);
        };
        servicePlanceService.updateOnly(servicePlan);
        servicePlanceService.confirmToApp(servicePlan);
        return servicePlan;
    }

    /**
     * cash Purchase from out
     * 根据工单和询价单，获取需要直接转工单数据
     * @param maintenanceOrders
     * @param
     * @return
     */
    public List<MaintenanceOrder> obtainCPFOMaintenanceOrder(List<MaintenanceOrder> maintenanceOrders){
        return maintenanceOrders.stream().filter(maintenanceOrder -> {
            return maintenanceOrder.getServicePlanItem().getOldInquiryNumber() != null;
        }).filter(maintenanceOrder -> {
            ServicePlanItem servicePlanItem = maintenanceOrder.getServicePlanItem();
//            Product product = maintenanceOrder.getProduct();
            String oldInquiryNumber = servicePlanItem.getOldInquiryNumber();

            ExternalInquiryItem inquiryItem = SpringManager.getBean(ExternalInquiryItemRepository.class).accordIdAndUniqueFind(oldInquiryNumber, servicePlanItem.getUniqueValue());
//            if (inquiryItem == null && servicePlanItem.getSupplier() != null && servicePlanItem.getSupplier().getId().equals("004465"))
//                throw new RuntimeException(" 商品：[" + product.getId() + "]" + product.getName() + " ,属于[现金外采]，<br/> 需发起【外采询价】审批通过后方可确认方案。\n");

            if (inquiryItem!=null){
//                ExternalInquiry externalInquiry = inquiryItem.getExternalInquiry();
                maintenanceOrder.setInquiryReasonType(inquiryItem.getInquiryReasonType());
                maintenanceOrder.setDeptRemark(inquiryItem.getDeptRemark());
                maintenanceOrder.setSettlementType(inquiryItem.getSettlementType());
                maintenanceOrder.setPlatformPriceCosInTaxTemp(inquiryItem.getDownCompanyPurchasePrice());
                List<Contract> contracts= SpringManager.getBean(ContractRepository.class).findAll(JpaDsl.toCriteria(
                        "validPeriod","GTE", new Date(),
                        "repealDate","EQ",   null,
                        "approveDate","NE",   null,
                        "consignInstall" , "EQ" , true,
                        "contractType.code","EQ","platform",
                        "partner.id","EQ","004465",
                        "settlementType.code","EQ","deptCash"));
                if(contracts.size() == 0) throw new RuntimeException("存在现金外采商品，需自动外协，没有找到对应合同，请检查");
                maintenanceOrder.setContract(contracts.stream().findFirst().get());
                maintenanceOrder.setOutAssistType("outPlatform");
                maintenanceOrder.setOutAssistTypeConfirm(false);
            }
            return inquiryItem != null;
        }).collect(Collectors.toList());
    }


    public MaintenanceOrder create(MaintenanceOrder maintenanceOrder){
        //新增的时候设置平台
        maintenanceOrder.setWorkPlatform(selectWorkPlatform(maintenanceOrder.getBelongDept(),maintenanceOrder.getProduct()));
        maintenanceOrder = save(maintenanceOrder);
        return maintenanceOrder;
    }

    public MaintenanceOrder create(MaintenanceOrder maintenanceOrder,Store store){
        //新增的时候设置平台

        maintenanceOrder.setWorkPlatform(selectWorkPlatform(store,maintenanceOrder.getProduct(),maintenanceOrder.getServeType()));
        maintenanceOrder = save(maintenanceOrder);
        return maintenanceOrder;
    }


    public MaintenanceOrder planCreateInnerWorkOrder(ServicePlan servicePlan, boolean isPickUpCar, ServicePlanItem servicePlanItem, String type) {
        MaintenanceOrder maintenanceOrder = new MaintenanceOrder();
        maintenanceOrder.setState(MaintenanceOrder.CONST_TABLE_STATE_INNER);
        maintenanceOrder.setLockState("appOrder".equals(servicePlan.getSourceBusinessType()) || isPickUpCar);
        maintenanceOrder.setDispatcheState("none");
        maintenanceOrder.setServicePlanItem(servicePlanItem);
        maintenanceOrder.setBelongDept(servicePlan.getBelongDept());
        maintenanceOrder.setCompany(servicePlan.getBelongDept().getCompany());
        maintenanceOrder.setFnCustomerExpand(servicePlan.getFnCustomerExpand());
        maintenanceOrder.setProduct(servicePlanItem.getProduct());
        maintenanceOrder.setUom(servicePlanItem.getUom());
        maintenanceOrder.setPlatform(servicePlanItem.getPlatform());
        maintenanceOrder.setSaleQty(servicePlanItem.getSaleQty());
        maintenanceOrder.setPriceCostUnitInTax(servicePlanItem.getPriceCostUnitInTax());
        maintenanceOrder.setPlatformPurchaseCost(servicePlanItem.getPlatformPurchaseCost());
        maintenanceOrder.setPlatformPriceCosInTax(servicePlanItem.getPlatformPriceCosInTax());
        maintenanceOrder.setProductRule(servicePlanItem.isProductRule());
        maintenanceOrder.setWorkState(MaintenanceOrder.WORK_ORDER_WORKSTATE_WAIT);
        maintenanceOrder.setCreator(servicePlan.getOperator1().getId());
        maintenanceOrder.setSaleChannel(servicePlan.getChannel());
        maintenanceOrder.setSupplierRef(servicePlan.getSupplierRef());
        insertWorkOrderBusiness(maintenanceOrder,type);
        MaintenanceOrder m = maintenanceOrderRepository.findAll(JpaDsl.toCriteriaByEq("servicePlanItem.id",maintenanceOrder.getServicePlanItem().getId(),"businessType","common")).stream().findFirst().orElse(null);
        if(m != null) throw new RuntimeException("产生重复工单，请重新刷新界面");
//        maintenanceOrder =  create(maintenanceOrder,store);
        maintenanceOrder =  create(maintenanceOrder);
        return maintenanceOrder;
    }

    public MaintenanceOrder planCreateCommonWorkOrder(ServicePlan servicePlan, boolean isPickUpCar, ServicePlanItem servicePlanItem, String type) {
        MaintenanceOrder maintenanceOrder = new MaintenanceOrder();
        maintenanceOrder.setState(MaintenanceOrder.CONST_TABLE_STATE_CREATE);
        maintenanceOrder.setLockState("appOrder".equals(servicePlan.getSourceBusinessType()) || isPickUpCar);
        maintenanceOrder.setDispatcheState("none");
        maintenanceOrder.setServicePlanItem(servicePlanItem);
        maintenanceOrder.setBelongDept(servicePlan.getBelongDept());
        maintenanceOrder.setCompany(servicePlan.getBelongDept().getCompany());
        maintenanceOrder.setFnCustomerExpand(servicePlan.getFnCustomerExpand());
        maintenanceOrder.setProduct(servicePlanItem.getProduct());
        maintenanceOrder.setUom(servicePlanItem.getUom());
        maintenanceOrder.setPlatform(servicePlanItem.getPlatform());
        maintenanceOrder.setSaleQty(servicePlanItem.getSaleQty());
        maintenanceOrder.setPriceCostUnitInTax(servicePlanItem.getPriceCostUnitInTax());
        maintenanceOrder.setPlatformPurchaseCost(servicePlanItem.getPlatformPurchaseCost());
        maintenanceOrder.setPlatformPriceCosInTax(servicePlanItem.getPlatformPriceCosInTax());
        maintenanceOrder.setProductRule(servicePlanItem.isProductRule());
        maintenanceOrder.setWorkState(MaintenanceOrder.WORK_ORDER_WORKSTATE_WAIT);
        maintenanceOrder.setCreator(servicePlan.getOperator1().getId());
        maintenanceOrder.setSaleChannel(servicePlan.getChannel());
        maintenanceOrder.setSupplierRef(servicePlan.getSupplierRef());
        insertWorkOrderBusiness(maintenanceOrder,type);
        MaintenanceOrder m = maintenanceOrderRepository.findAll(JpaDsl.toCriteriaByEq("servicePlanItem.id",maintenanceOrder.getServicePlanItem().getId(),"businessType","common")).stream().findFirst().orElse(null);
        if(m != null) throw new RuntimeException("产生重复工单，请重新刷新界面");
//        maintenanceOrder =  create(maintenanceOrder,store);
        maintenanceOrder =  create(maintenanceOrder);
        return maintenanceOrder;
    }

    private void insertWorkOrderBusiness(MaintenanceOrder maintenanceOrder, String type) {
        switch (type){
            case "common":
                maintenanceOrder.setBusinessType(MaintenanceOrder.WORK_ORDER_COMMON);
                maintenanceOrder.setBusinessTypeName("服务工单");
                break;
            case "inner":
                maintenanceOrder.setBusinessType(MaintenanceOrder.WORK_ORDER_INNER);
                maintenanceOrder.setBusinessTypeName("内协工单");
                break;
            case "out":
                break;
                default:
                    break;

        }
    }


    public MaintenanceOrder planCreateInnerWorkOrder(ServicePlan servicePlan, boolean isPickUpCar, ServicePlanItem servicePlanItem, Store store) {
        MaintenanceOrder maintenanceOrder = new MaintenanceOrder();
        maintenanceOrder.setState(MaintenanceOrder.CONST_TABLE_STATE_CREATE);
        maintenanceOrder.setLockState("appOrder".equals(servicePlan.getSourceBusinessType()) || isPickUpCar);
        maintenanceOrder.setDispatcheState("none");
        maintenanceOrder.setServicePlanItem(servicePlanItem);
        maintenanceOrder.setBelongDept(servicePlan.getBelongDept());
        maintenanceOrder.setCompany(servicePlan.getBelongDept().getCompany());
        maintenanceOrder.setFnCustomerExpand(servicePlan.getFnCustomerExpand());
        maintenanceOrder.setProduct(servicePlanItem.getProduct());
        maintenanceOrder.setUom(servicePlanItem.getUom());
        maintenanceOrder.setPlatform(servicePlanItem.getPlatform());
        maintenanceOrder.setSaleQty(servicePlanItem.getSaleQty());
        maintenanceOrder.setPriceCostUnitInTax(servicePlanItem.getPriceCostUnitInTax());
        maintenanceOrder.setPlatformPurchaseCost(servicePlanItem.getPlatformPurchaseCost());
        maintenanceOrder.setPlatformPriceCosInTax(servicePlanItem.getPlatformPriceCosInTax());
        maintenanceOrder.setProductRule(servicePlanItem.isProductRule());
        maintenanceOrder.setBusinessType(MaintenanceOrder.WORK_ORDER_INNER);
        maintenanceOrder.setWorkState(MaintenanceOrder.WORK_ORDER_WORKSTATE_WAIT);
        maintenanceOrder.setCreator(servicePlan.getOperator1().getId());
        maintenanceOrder.setBusinessTypeName("内协工单");
        maintenanceOrder.setSaleChannel(servicePlan.getChannel());
        maintenanceOrder.setSupplierRef(servicePlan.getSupplierRef());
        MaintenanceOrder m = maintenanceOrderRepository.findAll(JpaDsl.toCriteriaByEq("servicePlanItem.id",maintenanceOrder.getServicePlanItem().getId(),"businessType","common")).stream().findFirst().orElse(null);
        if(m != null) throw new RuntimeException("产生重复工单，请重新刷新界面");
//        maintenanceOrder =  create(maintenanceOrder,store);
        maintenanceOrder =  create(maintenanceOrder);
        return maintenanceOrder;
    }

    /**
     * 新增修改操作
     * @param simpleRequest
     * @return
     */
    public List<MaintenanceOrder> createMaintenanceOrders(SimpleRequest simpleRequest){
        JSONObject jo = simpleRequest.getJO();
        JSONArray maintenanceOrdersArray = jo.getJSONArray("maintenanceOrders");
        List<MaintenanceOrder> maintenanceOrders = new ArrayList<MaintenanceOrder>();
        maintenanceOrdersArray.forEach((item)->{
            MaintenanceOrder maintenanceOrder = MapUtil.getO(item,MaintenanceOrder.class);
            //进行一个防重复验证
            MaintenanceOrder m = maintenanceOrderRepository.findAll(JpaDsl.toCriteriaByEq("servicePlanItem.id",maintenanceOrder.getServicePlanItem().getId(),"businessType","common")).stream().findFirst().orElse(null);
            if(m != null) throw new RuntimeException("产生重复工单，请重新刷新界面");
            maintenanceOrder =  create(maintenanceOrder);
            maintenanceOrders.add(maintenanceOrder);
        });
        return maintenanceOrders;
    }

    /**
     * 派工界面审核：派工
     * @param simpleRequest
     * @return
     */
    public Map dispatch(SimpleRequest simpleRequest){
        JSONObject jo = simpleRequest.getJO();
        List<MaintenanceOrder> maintenanceOrders =
                maintenanceOrdersTransfer(jo.getJSONArray("maintenanceOrders"));

        PartyRole person = getPerson(simpleRequest);
        if (person==null) person = SpringManager.getBean(PartyRoleRepository.class).findOne("system");

        maintenanceOrderOutWorkService.dispatchProcess(maintenanceOrders, person);

        MaintenanceOrder maintenanceOrder = maintenanceOrders.stream().findFirst().orElse(null);
        if(isCreateLogger(jo)) servicePlanceService.addServicePlanLogger(maintenanceOrder.getServicePlanItem().getServicePlan(),"外协派工","");

        return this.invoke("fn.maintenance.findDispachOrder",MapUtil.mapper("SERVICE_PLAN_ID",maintenanceOrders.stream().findFirst().get().getServicePlanItem().queryServicePlanByItem().getId(),"STATE","waitDispatch"));
    }
//
//    /**
//     * 外协派工(App操作)
//     * @param simpleRequest
//     * @return
//     */
//    public Map dispatchForApp(SimpleRequest simpleRequest){
//        JSONObject jo = simpleRequest.getJO();
//        String id = jo.getString("id");
//        MaintenanceOrder one = maintenanceOrderRepository.findOne(id);
//        one.setSelected(true);
//        List<MaintenanceOrder> maintenanceOrders = Collections.singletonList(one);
//        PartyRole person = partyRoleRepository.findOne(jo.getString("operator"));
//
//        if (person==null)throw new RuntimeException("当前操作员不存在");
//
//        dispatchProcess(maintenanceOrders, person, "");
//
//        return MapUtil.mapper("success",true);
//    }



    /**
     * 派工界面退回：退回到原工单上
     * @param simpleRequest
     * @return
     */
    public Map dispatchBack(SimpleRequest simpleRequest){
        List<MaintenanceOrder> maintenanceOrders =
                maintenanceOrdersTransfer(simpleRequest.getJO().getJSONArray("maintenanceOrders"));
        PartyRole person = getPerson(simpleRequest);
        ServicePlan servicePlan = maintenanceOrderOutWorkService.dispatchBackProcess(maintenanceOrders, person);
        servicePlanceService.addServicePlanLogger(servicePlan,"外协派工退回","");
        return this.invoke("fn.maintenance.findDispachOrder",MapUtil.mapper("SERVICE_PLAN_ID",maintenanceOrders.stream().findFirst().get().getServicePlanItem().queryServicePlanByItem().getId(),"STATE","waitDispatch"));
    }



    /**
     * 派工界面编辑
     * @param simpleRequest
     * @return
     */
    public Map dispachOrderUpdate(SimpleRequest simpleRequest){
        List<MaintenanceOrder> maintenanceOrders =
                maintenanceOrdersTransfer(simpleRequest.getJO().getJSONArray("maintenanceOrders"));
        maintenanceOrderOutWorkService.dispachOrderUpdateProecss(maintenanceOrders);

        return this.invoke("fn.maintenance.findDispachOrder",MapUtil.mapper("SERVICE_PLAN_ID",maintenanceOrders.stream().findFirst().get().getServicePlanItem().queryServicePlanByItem().getId(),"STATE","waitDispatch"));
    }

    public JSONObject getNewCG01Map(Map map) {
        JSONObject result = new JSONObject();
        result.put("conditionStrategyId", "CG01");
        result.put("SYS_RQ", new Date());
        result.put("SYS_NO_CHECK", "SUPPLIER_ID");

        result.put("PRODUCT_ID", map.get("SPID") == null ? null : map.get("SPID"));
        return result;
    }


    /**
     * 派工格式化
     * @param maintenanceOrders
     * @param servicePlan
     * @param state
     * @return
     */
    private Map dispatchReturnFormat(List<MaintenanceOrder> maintenanceOrders, ServicePlan servicePlan, String state) {
        MaintenanceOrder maintenanceOrder = maintenanceOrders.stream().findFirst().get();
//        List<String> conditionList = maintenanceOrders.stream().map(maintenanceOrder1 -> maintenanceOrder1.getServicePlanItem().getOldInquiryNumber()).collect(Collectors.toList());
//        JSONArray jsonArray = conditionList.size()>0?serviceToForeign.qryXJInfoFromOldSys(conditionList):new JSONArray();
        JSONArray jsonArray = new JSONArray();
        maintenanceOrders.forEach(maintenanceOrder1 -> {
            if (maintenanceOrder1.getPlatformPriceCosInTaxTemp()>0)return;
            Double P001 = 0.0;
            try {
                Object obj = this.invoke("condition.execConditionStrategy",getNewCG01Map(MapUtil.mapper("SPID",maintenanceOrder1.getProduct().getId())));
                JSONObject CG01 = JSONObject.parseObject(JSONObject.toJSONString(obj));
                P001= CG01.getDoubleValue("P001");
            }catch (Exception e){
                P001 = 0.0;
            }
//            String oldInquiryNumber = maintenanceOrder1.getServicePlanItem().getOldInquiryNumber();
//            for (Object item : jsonArray) {
//                JSONObject tempJson = (JSONObject)item;
//                if(oldInquiryNumber!=null&& oldInquiryNumber.equals(tempJson.getString("XJDH"))
//                        && maintenanceOrder1.getProduct().getId().equals(tempJson.getString("SPID"))){
//                    P001=((JSONObject)tempJson).getDoubleValue("XYGSCGJ");
//                }
//            }

            maintenanceOrder1.setPlatformPriceCosInTaxTemp(P001>0?P001:maintenanceOrder1.getPriceCostUnitInTaxTemp());
            maintenanceOrder1 = maintenanceOrderRepository.saveAndFlush(maintenanceOrder1);
        });

        return mapper("belongDept", maintenanceOrder.getBelongDept(),
                "fnCustomerExpand", maintenanceOrder.getFnCustomerExpand(),
                "customerCar", maintenanceOrder.getFnCustomerExpand(),
                "platform",maintenanceOrder.getPlatform().getParty().getName(),
                "customer", maintenanceOrder.getFnCustomerExpand(),
                "servicePlan", servicePlan,
                "sourceBusinessTypeName", servicePlan.getSourceBusinessTypeName(),
                "sourceFrom", servicePlan.getSourceFrom(),
                "remark",servicePlan.getDeptRemark(),
                "sourceFromShow",servicePlan.getSourceBusinessTypeName() == null ? "" : servicePlan.getSourceFrom() + "(" + servicePlan.getSourceBusinessTypeName() + ")",
                "SERVICE_PLAN_ID", servicePlan.getId(),
                "STATE", state,
                "outAssistType",maintenanceOrder.getOutAssistType(),
                "outAssistTypeConfirm",maintenanceOrder.isOutAssistTypeConfirm(),
                "containSpace",maintenanceOrder.isContainSpace(),
                "editFlag", maintenanceOrders.stream().filter((maintenanceOrder1) -> {
                    return "waitDispatch".equals(maintenanceOrder1.getDispatcheState());
                }).collect(Collectors.toList()).size() != 0,
                "maintenanceOrders", maintenanceOrders
        );
    }


    public Map findDispachOrderBDeal(SimpleRequest re){
        JSONObject jo = re.getJO();
        String SERVICE_PLAN_ID = jo.getString("SERVICE_PLAN_ID");
        String state = jo.getString("STATE");
        String id = jo.getString("businessKey");

        if(SERVICE_PLAN_ID == null) {
            Optional.ofNullable(id).orElseThrow(()->new RuntimeException("跳转单号为空，请检查"));
            MaintenanceOrder m = maintenanceOrderRepository.findOne(id);
            SERVICE_PLAN_ID = m.getServicePlanItem().getServicePlan().getId();
            state = m.getDispatcheState();
        }
        return MapUtil.mapper("SERVICE_PLAN_ID",SERVICE_PLAN_ID,"STATE",state);
    }


    /**
     * 派工跳转
     * @param simpleRequest
     * @return
     */
    public Map findDispachOrder(SimpleRequest simpleRequest) {
        JSONObject jo = simpleRequest.getJO();
        String SERVICE_PLAN_ID = jo.getString("SERVICE_PLAN_ID");
        String state = jo.getString("STATE");
        ServicePlan servicePlan = servicePlanRepository.findOne(SERVICE_PLAN_ID);

        switch (state){
            case "已派工": state = "dispatch";
                break;
            case "退回": state = "back";
                break;
            case "未派工": state = "waitDispatch";
                break;
            default : break;
        }
        List<String> list = servicePlan.getServicePlanItems().stream().map((servicePlanItem)->{
            return servicePlanItem.getId();
        }).collect(Collectors.toList());

        List<MaintenanceOrder> maintenanceOrders
                = maintenanceOrderRepository.findOutDiapatcherOrder(state,list);

        if (maintenanceOrders.size() == 0) {
            return new HashMap();
        }
        return dispatchReturnFormat(maintenanceOrders, servicePlan, state);
    }
    /**
     * 根据方案明细行，查找工时明细行
     * @param
     * @return
     */
    private Map findMaintenanceOrderByServicePlan(SimpleRequest simpleRequest) {
        //进入工单界面了两种形式，从工单号进入，从方案好进入
        String plan_id = simpleRequest.getJO().getString("SERVICE_PLAN_ID"); //方案编码
        String work_id = simpleRequest.getJO().getString("id"); //工单编码
        ServicePlan servicePlan = null ;
        if(plan_id != null){
            servicePlan = servicePlanRepository.findOne(plan_id);
        }else{
            MaintenanceOrder maintenanceOrder = maintenanceOrderRepository.findOne(work_id);
            if(maintenanceOrder == null) throw new RuntimeException("该工单号不存在，请检查");
            servicePlan = maintenanceOrder.getServicePlanItem().getServicePlan();
        }
       if(servicePlan == null) throw new RuntimeException("传入数据有误，未找到合适方案号，联系开发人员解决");
        return structureMaintenanceByServicePlan(servicePlan,simpleRequest.getJO().getString("operateState"),true);
    }

    public Map findOutMaintenanceOrderBDeal(SimpleRequest re){
        JSONObject jo = re.getJO();
        String SERVICE_PLAN_ID = jo.getString("SERVICE_PLAN_ID");
        String state = jo.getString("STATE");
        String id = jo.getString("businessKey");
        if(SERVICE_PLAN_ID == null) {
            Optional.ofNullable(id).orElseThrow(()->new RuntimeException("跳转单号为空，请检查"));
            List<MaintenanceOrder> maintenanceOrders = maintenanceOrderRepository.findOutOrderByCommonOrder(id);
            if(maintenanceOrders.size() == 0) throw new RuntimeException("不存在对应的外协工单");
            MaintenanceOrder m = maintenanceOrders.stream().findFirst().get();
            SERVICE_PLAN_ID = m.getServicePlanItem().getServicePlan().getId();
            state = m.getDispatcheState();
        }
        return MapUtil.mapper("SERVICE_PLAN_ID",SERVICE_PLAN_ID,"STATE",state);
    }


    public Map findOutMaintenanceOrder(SimpleRequest simpleRequest){
        JSONObject jo = simpleRequest.getJO();
        String state = jo.getString("STATE");
        String SERVICE_PLAN_ID = jo.getString("SERVICE_PLAN_ID");
        ServicePlan servicePlan = servicePlanRepository.findOne(SERVICE_PLAN_ID);

        List<String> list = servicePlan.getServicePlanItems().stream().map(servicePlanItem -> {
            return servicePlanItem.getId();
        }).collect(Collectors.toList());
        List<MaintenanceOrder> maintenanceOrders = maintenanceOrderRepository.findOutMaintenanceOrder(state,list);
        return outReturnFormat(maintenanceOrders, servicePlan);
    }



    /**
     * 根据方案明细行，查找工时明细行
     * @param servicePlanItem
     * @return
     */
    private MaintenanceOrder findMaintenanceOrderByServicePlanItem(ServicePlanItem servicePlanItem) {
        List<MaintenanceOrder> list = maintenanceOrderRepository.findAll(JpaDsl.toCriteriaByEq("servicePlanItem.id",servicePlanItem.getId()));
        if(list.size() > 1){
            throw new RuntimeException("程序错误：一条方案明细生成多份施工信息");
        }else if(list.size() != 1){
            return null;
        }
        return list.stream().findFirst().get();
    }

    /**
     * 当前门店 + 车牌  找需要施工的商品
     * @param dept
     * @param fnCustomerExpand
     * @return
     */
    public List<MaintenanceOrder> findNeedWorkingMaintenanceOrder(Dept dept,FnCustomerExpand fnCustomerExpand){
        List<MaintenanceOrder> maintenanceOrders = maintenanceOrderRepository.findMaintenanceOrderForWork(dept.getId(),fnCustomerExpand.getId());
        return maintenanceOrders;
    }

    /**
     * 当前门店 + 车牌  找完工商品本次绑定的方案
     * （
     * 方案确认后的，未终止的。
     * ）
     * @param dept
     * @param fnCustomerExpand
     * @return
     */
    public List<ServicePlan> findQualityTestServicePlan(Dept dept,FnCustomerExpand fnCustomerExpand){
        List<ServicePlan> servicePlans = servicePlanRepository.findQualityTestServicePlan(dept,fnCustomerExpand);
        return servicePlans;
    }

    /**
     * 找对应的来源工单行
     * @param maintenanceOrder
     * @return
     */
    private MaintenanceOrder findOrigin(MaintenanceOrder maintenanceOrder) {
        ServicePlanItem servicePlanItem= maintenanceOrder.getServicePlanItem().getParentServicePlanItem();
        if(servicePlanItem == null) return null;
        MaintenanceOrder maintenanceOrder1 = findMaintenanceOrderByServicePlanItem(servicePlanItem);
        return maintenanceOrder1;
    }

    /**
     * 找工时绑定的配件
     * @param id
     * @return
     */
    private List<ServicePlanItem> findPartsByMaintenanceOrder(String id) {
        List list = servicePlanItemRepository.findAll(JpaDsl.toCriteriaByEq(
                "relevanceWorkOrder",id
        ));
        return list;
    }

    /**
     * 根据门店  找待质检方案
     * @return
     */
    public List<ServicePlan> findServicePlanWaitQualityTestByDept(Dept dept){
        List<ServicePlan> list = servicePlanRepository.findAll(
                JpaDsl.toCriteriaByEq(
                        "belongDept.id",dept.getId(),
                        "finishWork",true,
                        "qualityTestDate",null
                )
        );
        return list;
    }
    /**
     * 根据门店+本次服务车辆信息  本次施工完成后的数据
     * @return
     */
    public List<ServicePlan> findServicePlanWaitQualityTestByDeptAndFnCustomerExpand(Dept dept,FnCustomerExpand fnCustomerExpand){
        List<ServicePlan> list = servicePlanRepository.findAll(
                JpaDsl.toCriteriaByEq(
                        "belongDept.id",dept.getId(),
                        "finishWork",true,
                        "fnCustomerExpand.id",fnCustomerExpand.getId()
                )
        );
        return list;
    }

    /**
     * 根据车牌，帅选出待质检明细
     * @param dept
     * @return
     */
    private List<ServicePlan> findWaitQualityTestAmountServicePlan(Dept dept){
        //1.查找施工完成，未质检方案
        List<ServicePlan> servicePlans = findServicePlanWaitQualityTestByDept(dept);
        return fillterAllPartsServicePlan(servicePlans);
    }

    /**
     * 施工完成，回写数据
     * @param maintenanceOrder
     * @return
     */
    private MaintenanceOrder finishMaintenance(MaintenanceOrder originMaintenanceOrder,MaintenanceOrder maintenanceOrder){
        originMaintenanceOrder.setState(MaintenanceOrder.CONST_TABLE_STATE_FINISH);
        originMaintenanceOrder.setWorkState(MaintenanceOrder.WORK_ORDER_WORKSTATE_FINISH);
        originMaintenanceOrder.setFinishDate(new Date());
        originMaintenanceOrder.setFinishUid(maintenanceOrder.getOperator1());
//        //更改本单状态
//        maintenanceOrder.setWorkState(MaintenanceOrder.WORK_ORDER_WORKSTATE_WORKING);
//        maintenanceOrder = maintenanceOrderRepository.saveAndFlush(maintenanceOrder);
//        //更新对应方案明细，设置完成状态
//        String servicePlanItemId = maintenanceOrder.getServicePlanItem().getId();
//        ServicePlan servicePlan = maintenanceOrder.getServicePlanItem().getServicePlan();
//        servicePlan.getServicePlanItems().forEach(servicePlanItem -> {
//            if(servicePlanItem.getId().equals(servicePlanItemId))
//                servicePlanItem.setFinishDate(new Date());
//        });
//        //更新对应方案主表，判断是否整单完成
//        List list = servicePlan.getServicePlanItems().stream().filter(servicePlanItem -> {
//            return servicePlanItem.isServiceState() && !servicePlanItem.isTerminationFlag() && servicePlanItem.getFinishDate() == null;
//        }).collect(Collectors.toList());
//        if(list.size() == 0) servicePlan.setFinishWork(true);
//        servicePlan = servicePlanceService.updateOnly(servicePlan);
//
//        return maintenanceOrderRepository.findOne(maintenanceOrder.getId());
        return originMaintenanceOrder;
    }

    /**
     * 过滤纯配件方案
     * @param servicePlans
     * @return
     */
    private List<ServicePlan> fillterAllPartsServicePlan(List<ServicePlan> servicePlans){
        servicePlans = servicePlans.stream().filter((servicePlan)->{
            return servicePlan.checkQualityTestProduct();
        }).collect(Collectors.toList());
        return servicePlans;
    }

    /**
     * 根据车牌，帅选出待质检明细
     * @param servicePlans
     * @return
     */
    private Map findWaitQualityTestAmountServicePlan(List<ServicePlan> servicePlans){
        //1.根据车牌分组
        Map map = servicePlans.stream().collect(Collectors.groupingBy((servicePlan)->{
            return servicePlan.getFnCustomerExpand().getId();
        }));
        return map;
    }

    /**
     * 完成施工
     * @param simpleRequest
     * @return
     */
    public Map finishConstruction(SimpleRequest simpleRequest){
        MaintenanceOrder originMaintenanceOrder = simpleRequest.getO(MaintenanceOrder.class);
        MaintenanceOrder maintenanceOrder = maintenanceOrderRepository.findOne(originMaintenanceOrder.getId());
        if(maintenanceOrder == null) throw new RuntimeException("无效工单号");
        if(maintenanceOrder.getFinishDate() != null) MapUtil.mapper("success",true);
        if(maintenanceOrder.isLockState()) throw new RuntimeException("工单在锁定状态，无法完成施工");
        if(MaintenanceOrder.WORK_ORDER_WORKSTATE_FINISH.equals(maintenanceOrder.getWorkState()) || maintenanceOrder.getFinishDate() != null) throw new RuntimeException("工单已经完成施工，无需重复完成");


        if("out".equals(maintenanceOrder.getBusinessType())){
            throw new RuntimeException(maintenanceOrder.getProduct().getName() + "是外协商品，请在PC端外协工单界面完工");
        }

        ServicePlanItem servicePlanItem = maintenanceOrder.getServicePlanItem();
        if(servicePlanItem.isPaintFlag()) throw new RuntimeException("带安商品需要转外协完工");

        maintenanceOrder.setOperator1(originMaintenanceOrder.getOperator1());

        if(maintenanceOrder.getServicePlanItem().getServicePlan().getOldFrameSourceFrom() == null){  //老框架过来的施工，不需要写判断
            //检测是否处于施工中
            if(!MaintenanceOrder.WORK_ORDER_WORKSTATE_WORKING.equals(maintenanceOrder.getWorkState())) throw new RuntimeException("该工单不处于施工中，无法完成");

            //施工写记录
            ConstructionRecord constructionRecord
                    = constructionRecordService.constructionRecord(maintenanceOrder,ConstructionRecord.CONST_TABLE_OPERATETYPE_FINISH,"");
            this.invoke("fn.constructRecord.createOrUpdate",MapUtil.mapped(constructionRecord));

//            calcutelateTimeNow(constructionRecord,maintenanceOrder);
        }
        maintenanceOrder.setState(MaintenanceOrder.CONST_TABLE_STATE_FINISH);
        maintenanceOrder.setWorkState(MaintenanceOrder.WORK_ORDER_WORKSTATE_FINISH);
        maintenanceOrder.setFinishUid(originMaintenanceOrder.getOperator1());
        maintenanceOrder.setFinishDate(new Date());
        finishWork(maintenanceOrder); //施工调用
        //最后一个(除外协)完工的回写方案完工日志
        lastWorkingToFinishWriteLogger(servicePlanItem.getServicePlan());
        return MapUtil.mapper("success",true);
    }

    private void lastWorkingToFinishWriteLogger(ServicePlan servicePlan) {
        String planId = servicePlan.getId();
        List types = new ArrayList();
        types.add("common");
        types.add("inner");
        List<MaintenanceOrder> workStateByServicePlan = maintenanceOrderRepository.findWorkStateByServicePlan(planId, MaintenanceOrder.WORK_ORDER_WORKSTATE_FINISH,types);
        List<MaintenanceOrder> maintenanceOrders = maintenanceOrderRepository.findByServicePlanAndBusinessType(planId,types);
        if (workStateByServicePlan.size()==maintenanceOrders.size()) {
            servicePlanceService.addServicePlanLogger(servicePlan,"完成施工","");
        }
    }

    /**
     * 完工调用
     * @param maintenanceOrder
     * @return
     */
    public MaintenanceOrder finishWork(MaintenanceOrder maintenanceOrder){
        reWriteBackData(maintenanceOrder,"finish");
        return maintenanceOrder;
    }

    /**
     * 质检队列
     * @param
     * @return
     */
    private List<Map> getStyleList(List<ServicePlan> servicePlans) {
        List list = new ArrayList();
        Map machineRepaMap = new HashMap();
        machineRepaMap.put("style","machineRepa");
        machineRepaMap.put("qty",0);
        Map cosmetologyMap = new HashMap();
        cosmetologyMap.put("style","cosmetology");
        cosmetologyMap.put("qty",0);
        Map sprayPaintMap = new HashMap();
        sprayPaintMap.put("style","sprayPaint");
        sprayPaintMap.put("qty",0);

        servicePlans.stream().forEach((servicePlan)->{
            if(servicePlan.returnTypeItems("machineRepa").size() != 0) machineRepaMap.put("qty",(Integer)machineRepaMap.get("qty") + 1);
            if(servicePlan.returnTypeItems("cosmetology").size() != 0) cosmetologyMap.put("qty",(Integer)cosmetologyMap.get("qty") + 1);
            if(servicePlan.returnTypeItems("sprayPaint").size() != 0) sprayPaintMap.put("qty",(Integer)sprayPaintMap.get("qty") + 1);
        });

        if((Integer)machineRepaMap.get("qty") != 0)list.add(machineRepaMap);
        if((Integer)cosmetologyMap.get("qty") != 0)list.add(cosmetologyMap);
        if((Integer)sprayPaintMap.get("qty") != 0)list.add(sprayPaintMap);

        return list;
    }

    /**
     * 质检队列明细
     * @param
     * @return
     */
    private List getStyleListDetail(List<ServicePlan> servicePlans) {
        List<Map> list = getStyleList(servicePlans);
        list.forEach((item)->{
            String type = (String)item.get("style");
            item.put("servicePlanItems",servicePlans.stream().filter((servicePlan)->{                return servicePlan.returnTypeItems(type).size() != 0;
            }).map((servicePlan)->{
                return MapUtil.mapper(
                        "id",servicePlan.getId(),
                        "state",servicePlan.checkFinishQualityTestByStyle(type),
                        "qualityTestUid",servicePlan.returnTypeItems(type).stream().findFirst().get().getQualityTestUid(),
                        "qualityTestDate",servicePlan.returnTypeItems(type).stream().findFirst().get().getQualityTestDate(),
                        "workItems",servicePlan.returnTypeItems(type).stream().map(servicePlanItem->{
                            return MapUtil.mapper(
                                    "id",servicePlanItem.getId(),
                                    "product",MapUtil.mapper("id",servicePlanItem.getProduct().getId(),"name",servicePlanItem.getProduct().getName()),
                                    "finishDate",servicePlanItem.returnMaintenanceOrder().getFinishDate(),
                                    "vv",servicePlanItem.returnMaintenanceOrder().returnWorker(),
                                    "partsItems",findPartsByMaintenanceOrder(servicePlanItem.returnMaintenanceOrder().getId()).stream().map((servicePlanItem1)->{
                                        return MapUtil.mapper(
                                                "id",servicePlanItem1.getId(),
                                                "product",MapUtil.mapper("id",servicePlanItem1.getProduct().getId(),"name",servicePlanItem1.getProduct().getName()),
                                                "saleQty",servicePlanItem1.getSaleQty()
                                        );
                                    }).collect(Collectors.toList())
                            );
                        }).collect(Collectors.toList())
                );
            }).collect(Collectors.toList()));

        });
        return list;
    }

    /**
     * 工单操作转化成对应list
     * @param arrays
     * @return
     */
    public List<MaintenanceOrder> maintenanceOrdersTransfer(JSONArray arrays){
        List<MaintenanceOrder> maintenanceOrders = new ArrayList<>();
        arrays.stream().forEach((tempJson)->{
//            JSONObject json = (JSONObject)tempJson;
//            MaintenanceOrder maintenanceOrder = maintenanceOrderRepository.findOne(json.getString("id"));
//            maintenanceOrder.setVersion(json.getInteger("version"));

            MaintenanceOrder maintenanceOrder = MapUtil.getO(tempJson,MaintenanceOrder.class);
            maintenanceOrders.add(maintenanceOrder);
        });
        return maintenanceOrders;
    }

    /**
     * 外协重新派工(erp操作)
     * @param simpleRequest
     * @return
     */
    public Map outBack(SimpleRequest simpleRequest){
        List<MaintenanceOrder> maintenanceOrders =
                maintenanceOrdersTransfer(simpleRequest.getJO().getJSONArray("maintenanceOrders"));

        PartyRole person = getPerson(simpleRequest);

        ServicePlanItem servicePlanItem = maintenanceOrderOutWorkService.reDispatchProcess(maintenanceOrders, person);

        return outReturnFormat(maintenanceOrders, servicePlanItem.queryServicePlanByItem());
    }
    /**
     * 外协派工:外协退回(App操作)
     * @param simpleRequest
     * @return
     */
    public Map outBackForApp(SimpleRequest simpleRequest){
        JSONObject jo = simpleRequest.getJO();
        String id = jo.getString("id");
//        if ("waitDispatch".equals(jo.getString("state")))

//        List<MaintenanceOrder> maintenanceOrders = commonOrderFindOutOrder(id,maintenanceOrder -> !maintenanceOrder.getState().equals("create"));
        MaintenanceOrder maintenanceOrder = maintenanceOrderRepository.findOne(id);
        maintenanceOrder.setSelected(true);
        PartyRole person = partyRoleRepository.findOne(jo.getString("operator"));

        if (person==null)throw new RuntimeException("当前操作员不存在");

        User user =userRepository.findAll(JpaDsl.toCriteriaByEq("person.id",person.getId())).stream().findFirst().orElse(null);

        ServicePlan servicePlan = maintenanceOrderOutWorkService.dispatchBackProcess(Collections.singletonList(maintenanceOrder), person);

        servicePlanceService.addServicePlanLogger(servicePlan,"外协派工退回","",user.getId());
        return MapUtil.mapper("success",true);
    }

    /**
     * 外协工单:重新派工(App操作)
     * @param simpleRequest
     * @return
     */
    public Map reDispatchForApp(SimpleRequest simpleRequest){
        JSONObject jo = simpleRequest.getJO();
        String id = jo.getString("id");

        List<MaintenanceOrder> maintenanceOrders = commonOrderFindOutOrder(id,maintenanceOrder -> !maintenanceOrder.getState().equals("create"));

        PartyRole person = partyRoleRepository.findOne(jo.getString("operator"));
        if (person==null)throw new RuntimeException("当前操作员不存在");

        maintenanceOrderOutWorkService.reDispatchProcess(maintenanceOrders, person);
        return MapUtil.mapper("success",true);
    }

    /**
     * 普通工单获取外协工单
     * @param id
     * @return 长度小于等于1的工单数组
     */
    private List<MaintenanceOrder> commonOrderFindOutOrder(String id, Predicate<MaintenanceOrder> maintenanceOrderPredicate) {
        MaintenanceOrder one = maintenanceOrderRepository.findOne(id);
        ServicePlanItem servicePlanItem = one.getServicePlanItem();
        List<MaintenanceOrder> maintenanceOrders = maintenanceOrderRepository.findByServicePlanItemAndBusinessType(servicePlanItem.getId(), Collections.singletonList("out"));
        if (maintenanceOrders.isEmpty())throw new RuntimeException("不存在外协工单");
        if (maintenanceOrders.size()>1)throw new RuntimeException("存在多份外协工单");
        if (maintenanceOrderPredicate.test(maintenanceOrders.get(0))) throw new RuntimeException("工单数据类型有误");
        return maintenanceOrders;
    }



    /**
     * 外协完工(erp操作)
     * @param simpleRequest
     * @return
     */
    public Map outFinish(SimpleRequest simpleRequest){
        List<MaintenanceOrder> maintenanceOrders =
                maintenanceOrdersTransfer(simpleRequest.getJO().getJSONArray("maintenanceOrders"));
        PartyRole person = getPerson(simpleRequest);

        outFinishProcess(maintenanceOrders, person);

        return outReturnFormat(maintenanceOrders,maintenanceOrders.stream().findFirst().get().getServicePlanItem().queryServicePlanByItem());
    }

    /**
     * 外协完工(App操作)
     * @param simpleRequest
     * @return
     */
    public Map outFinishForApp(SimpleRequest simpleRequest){
        JSONObject jo = simpleRequest.getJO();
        String id = jo.getString("id");

        List<MaintenanceOrder> maintenanceOrders = commonOrderFindOutOrder(id,maintenanceOrder -> !maintenanceOrder.getState().equals("create"));

        PartyRole person = partyRoleRepository.findOne(jo.getString("operator"));
        if (person==null)throw new RuntimeException("当前操作员不存在");

        outFinishProcess(maintenanceOrders, person);

        return MapUtil.mapper("success",true);
    }

    /**
     * 外协完工主要处理逻辑
     * @param maintenanceOrders
     * @param person
     */
    private void outFinishProcess(List<MaintenanceOrder> maintenanceOrders, PartyRole person) {
        //全选
        maintenanceOrders.forEach(maintenanceOrder -> {
            //先判断是否已经完成了
            if(maintenanceOrder.getFinishDate() != null) throw new RuntimeException("重新查询数据，无需重复完工");

            maintenanceOrder.setSelected(true);

            //设置价格
            maintenanceOrder.setPlatformPriceCosInTax(maintenanceOrder.getPlatformPriceCosInTaxTemp());
            maintenanceOrder.setPriceCostUnitInTax(maintenanceOrder.getPriceCostUnitInTaxTemp());
            maintenanceOrder.setState(MaintenanceOrder.CONST_TABLE_STATE_FINISH);
            maintenanceOrder.setWorkState(MaintenanceOrder.WORK_ORDER_WORKSTATE_FINISH);
            maintenanceOrder.setFinishDate(new Date());
            if(!Objects.isNull(person)) maintenanceOrder.setFinishUid(person);
            maintenanceOrder = save(maintenanceOrder);

            if(!maintenanceOrder.isProductRule()){
                //非带安商品，重新取仓库
                Location loc = SpringManager.getBean(LocationService.class).findLocationByDept(maintenanceOrder.getBelongDept(),true);
                if (loc == null) throw new RuntimeException("该门店未设置带安虚拟库，请先设置,门店：" + maintenanceOrder.getBelongDept().getName());
                maintenanceOrder.setLocation(loc);
            }

            //回写数据(回写来源工单以下的所有单据)
            MaintenanceOrder originOrder = maintenanceOrderRepository.findOne(maintenanceOrder.getSourceFrom());
            if(originOrder == null) throw new RuntimeException("来源单据出现错误，请检查");

            maintenanceOrder.setOperator1(maintenanceOrder.getFinishUid());
            originOrder= outFinishReWrite(originOrder,maintenanceOrder);
            originOrder = reWriteBackData(originOrder,"outFinish");
        });
        // 带安商品
        // 带安采购, 正常销售
        String payload = JSONObject.toJSONString(MapUtil.mapper("maintenanceOrders", maintenanceOrders.stream().map(maintenanceOrder-> MapUtil.mapped(maintenanceOrder) ).collect(Collectors.toList())));
        publish(payload, maintenanceOrders.get(0).getServicePlanId());
    }

    public Map outTermination(SimpleRequest simpleRequest){
        List<MaintenanceOrder> maintenanceOrders =
                maintenanceOrdersTransfer(simpleRequest.getJO().getJSONArray("maintenanceOrders"));

        maintenanceOrders.forEach(maintenanceOrder -> {
            maintenanceOrder.setSelected(true);
            maintenanceOrder.setState(MaintenanceOrder.CONST_TABLE_STATE_TERMINATION);
            maintenanceOrder.setTerminationDate(new Date());
            maintenanceOrder.setTerminationUid(getPerson(simpleRequest));
            maintenanceOrder = save(maintenanceOrder);

            //回写数据(zhognzhi)
            MaintenanceOrder originOrder = maintenanceOrderRepository.findOne(maintenanceOrder.getSourceFrom());
            if(originOrder == null) throw new RuntimeException("来源单据出现错误，请检查");

            maintenanceOrder.setOperator1(getPerson(simpleRequest));
            originOrder= outTerminationReWrite(originOrder,maintenanceOrder);
            originOrder = reWriteBackData(originOrder,"outTermination");
        });
        ServicePlanItem servicePlanItem = maintenanceOrders.stream().findFirst().get().getServicePlanItem();
        ServicePlan servicePlan = servicePlanItem.getServicePlan();
        maintenanceOrders.stream().forEach(maintenanceOrder -> servicePlanItemWorkState(maintenanceOrder,servicePlan,"termination",false));
        servicePlanceService.updateOnly(servicePlan);
        servicePlanceService.addServicePlanLogger(servicePlan,"外协工单终止","");
        return outReturnFormat(maintenanceOrders,servicePlanItem.queryServicePlanByItem());
    }

    /**
     * 传入来源工单。
     * 外协完工回写
     * @param maintenanceOrder
     * @return
     */
    public MaintenanceOrder outFinishReWrite(MaintenanceOrder originMaintenanceOrder,MaintenanceOrder maintenanceOrder){
        originMaintenanceOrder.setFinishDate(new Date());
        originMaintenanceOrder.setFinishUid(maintenanceOrder.getOperator1());
        originMaintenanceOrder.setState(MaintenanceOrder.CONST_TABLE_STATE_FINISH);
        originMaintenanceOrder.setWorkState(MaintenanceOrder.WORK_ORDER_WORKSTATE_FINISH);
        //修改价格
        originMaintenanceOrder.setPlatformPriceCosInTax(maintenanceOrder.getPlatformPriceCosInTax());
        originMaintenanceOrder.setPriceCostUnitInTax(maintenanceOrder.getPriceCostUnitInTax());
        //设置仓库
        originMaintenanceOrder.setLocation(maintenanceOrder.getLocation());
        //设置供应商
        if(maintenanceOrder.getBelongDept().getCompany().getId().equals(originMaintenanceOrder.getBelongDept().getCompany().getId())){
            originMaintenanceOrder.setContract(maintenanceOrder.getContract());
        }

        return originMaintenanceOrder;
    }

    /**
     * 传入来源工单。
     * 外协终止递归
     * @param maintenanceOrder
     * @return
     */
    public MaintenanceOrder outTerminationReWrite(MaintenanceOrder originMaintenanceOrder,MaintenanceOrder maintenanceOrder){
        originMaintenanceOrder.setState(MaintenanceOrder.CONST_TABLE_STATE_TERMINATION);
        originMaintenanceOrder.setTerminationUid(maintenanceOrder.getOperator1());
        originMaintenanceOrder.setTerminationDate(new Date());
        return originMaintenanceOrder;
    }


    private ServicePlan outFinishSerivcePlan(MaintenanceOrder maintenanceOrder) {
        //更新对应方案明细，设置完成状态
        String servicePlanItemId = maintenanceOrder.getServicePlanItem().getId();
        ServicePlan servicePlan = maintenanceOrder.getServicePlanItem().getServicePlan();
        servicePlan.getServicePlanItems().forEach(servicePlanItem -> {
            if(servicePlanItem.getId().equals(servicePlanItemId)){
                servicePlanItem.setNeedQualityFlag(true);
                servicePlanItem.setFinishDate(new Date());
                servicePlanItem.setPlatformPriceCosInTax(maintenanceOrder.getPlatformPriceCosInTax());
                servicePlanItem.setPriceCostUnitInTax(maintenanceOrder.getPriceCostUnitInTax());
                servicePlanItem.setReferTax(maintenanceOrder.getPriceCostUnitInTax()+servicePlanItem.getSupplyChainManagement());
                if(maintenanceOrder.getLocation() != null) servicePlanItem.setLocation(maintenanceOrder.getLocation());
                servicePlanItem.setWorkState("treatQuality");
            }
        });

        //回写定损参考成本
        if (servicePlan.getSourceBusinessType() != null && servicePlan.getSourceBusinessType().equals("LossQuotation")){
            Product product = maintenanceOrder.getProduct();
            LossQuotation lossQuotation = SpringManager.getBean(LossQuotationRepository.class).findOne(servicePlan.getSourceFrom());
            if (lossQuotation!=null){
                lossQuotation.getLossQuotationItems().stream()
                        .filter(lossQuotationItem -> lossQuotationItem.getProduct().getId().equals(product.getId()))
                        .forEach(lossQuotationItem -> lossQuotationItem.setReferTax(maintenanceOrder.getPriceCostUnitInTax()+lossQuotationItem.getSupplyChainManagement()));
                lossQuotation.getLossQuotationPlans().stream()
                        .filter(lossQuotationItem -> lossQuotationItem.getProduct().getId().equals(product.getId()))
                        .forEach(lossQuotationItem -> lossQuotationItem.setReferTax(maintenanceOrder.getPriceCostUnitInTax()+lossQuotationItem.getSupplyChainManagement()));
                SpringManager.getBean(LossQuotationRepository.class).saveAndFlush(lossQuotation);
            }
        }
        if("finish".equals(servicePlan.checkResultByItem())){
            servicePlan.setFinishWork(true);
        }
        if (maintenanceOrderRepository.findOutOrderByServicePlan(servicePlan.getId()).size()==1) {
            User user = userRepository.findAll(JpaDsl.toCriteriaByEq("person.id", maintenanceOrder.getFinishUid().getId())).stream().findFirst().orElse(null);
            assert user != null;
            String remark = user.getName().equals("系统") ? servicePlan.getChannel().getName()+"自动完工" : "";
            servicePlanceService.addServicePlanLogger(servicePlan,"外协工单完成",remark,user.getId());
        }
        servicePlan = servicePlanceService.updateOnly(servicePlan);
        servicePlanceService.confirmToApp(servicePlan);
        return servicePlan;
    }

    private ServicePlan outTerminationSerivcePlan(MaintenanceOrder maintenanceOrder) {
        //更新对应方案明细，设置完成状态
        List<Product> products = new ArrayList<Product>();
        String servicePlanItemId = maintenanceOrder.getServicePlanItem().getId();
        ServicePlan servicePlan = maintenanceOrder.getServicePlanItem().getServicePlan();
        servicePlan.getServicePlanItems().forEach(servicePlanItem -> {
            if(servicePlanItem.getId().equals(servicePlanItemId)){
                servicePlanItem.setTerminationDate(new Date());
                servicePlanItem.setQtyEnd(servicePlanItem.getSaleQty());
                servicePlanItem.setTerminationUid(maintenanceOrder.getOperator1());
                products.add(servicePlanItem.getProduct());
            }
        });
        //更新对应方案主表，判断是否整单完成(可能是工单完成状态)
        List list = servicePlan.getServicePlanItems().stream().filter(servicePlanItem -> {
            return servicePlanItem.isServiceState() && servicePlanItem.getTerminationDate() == null && servicePlanItem.getFinishDate() == null;
        }).collect(Collectors.toList());
        if ("LossQuotation".equals(servicePlan.getSourceBusinessType())&&products.size()>0){
            SpringManager.getBean(LossQuotationService.class).writeBackLossQuotation(products,
                    servicePlan.getSourceFrom());
        }
        if(list.size() == 0){ //判断是否有完成的明细，有的话，直接完工
            List finishLsit = servicePlan.getServicePlanItems().stream().filter(servicePlanItem -> {
                return servicePlanItem.isServiceState() &&  servicePlanItem.getFinishDate() != null && servicePlanItem.getTerminationDate() == null;
            }).collect(Collectors.toList());

            if(finishLsit.size() != 0){
                servicePlan.setFinishWork(true);
            }else{
                servicePlan.setState("termination");
                servicePlan.setTerminationDate(new Date());
                servicePlan.setToPriceAuditUid(maintenanceOrder.getOperator1());
            }
        }
        servicePlanceService.addServicePlanLogger(servicePlan,"外协派工终止","");
        servicePlan = servicePlanceService.updateOnly(servicePlan);
        servicePlanceService.confirmToApp(servicePlan);
        return servicePlan;
    }

    /**
     * 外协格式化
     * @param maintenanceOrders
     * @param servicePlan
     * @return
     */
    private Map outReturnFormat(List<MaintenanceOrder> maintenanceOrders, ServicePlan servicePlan) {
        MaintenanceOrder maintenanceOrder = maintenanceOrders.stream().findFirst().get();
        return mapper("belongDept", maintenanceOrder.getBelongDept(),
                "fnCustomerExpand", maintenanceOrder.getFnCustomerExpand(),
                "customerCar", maintenanceOrder.getFnCustomerExpand(),
                "customer", maintenanceOrder.getFnCustomerExpand(),
                "servicePlan", servicePlan,
                "sourceBusinessTypeName", servicePlan.getSourceBusinessTypeName(),
                "sourceFrom", servicePlan.getSourceFrom(),
                "sourceFromShow",servicePlan.getSourceBusinessTypeName() == null ? "" : servicePlan.getSourceFrom() + "(" + servicePlan.getSourceBusinessTypeName() + ")",
                "remark",servicePlan.getDeptRemark(),
                "SERVICE_PLAN_ID", servicePlan.getId(),
                "editFlag", maintenanceOrders.stream().filter((maintenanceOrder1) -> {
                    return "create".equals(maintenanceOrder1.getState());
                }).count() != 0,
                "maintenanceOrders", maintenanceOrders
        );
    }

    /**
     * 暂停施工
     * @param simpleRequest MaintenanceOrder
     * @return Map
     */
    public Map pauseConstruction(SimpleRequest simpleRequest){
        String reasonId = "";
        try {
            reasonId = simpleRequest.getJO().getJSONObject("operateReason").getString("id");
        }catch (Exception e){

        }


        MaintenanceOrder originMaintenanceOrder = simpleRequest.getO(MaintenanceOrder.class);
        MaintenanceOrder maintenanceOrder = maintenanceOrderRepository.findOne(originMaintenanceOrder.getId());

        if(maintenanceOrder != null && maintenanceOrder.getFinishDate() != null) throw new RuntimeException("该工单不处于施工中，无需暂停");

//        if(!MaintenanceOrder.WORK_ORDER_WORKSTATE_WORKING.equals(maintenanceOrder.getWorkState())) throw new RuntimeException("工单不在施工中，无需暂停");
        maintenanceOrder.setOperator1(originMaintenanceOrder.getOperator1());
        //检测是否处于施工中
        if(!MaintenanceOrder.WORK_ORDER_WORKSTATE_WORKING.equals(maintenanceOrder.getWorkState())) throw new RuntimeException("该工单不处于施工中，无需暂停");

        //施工写记录
        ConstructionRecord constructionRecord
                = constructionRecordService.constructionRecord(maintenanceOrder,ConstructionRecord.CONST_TABLE_OPERATETYPE_PAUSE,reasonId);
        this.invoke("fn.constructRecord.createOrUpdate",MapUtil.mapped(constructionRecord));

        //更改本单状态
        maintenanceOrder.setWorkState(MaintenanceOrder.WORK_ORDER_WORKSTATE_PAUSE);
        calcutelateTimeNow(constructionRecord,maintenanceOrder);
        maintenanceOrder = maintenanceOrderRepository.saveAndFlush(maintenanceOrder);
        // 方案明细状态
        ServicePlan servicePlan = servicePlanItemWorkState(maintenanceOrder, maintenanceOrder.getServicePlanItem().getServicePlan(), "pause",true);
        //记录日志
        servicePlanceService.addServicePlanLogger(servicePlan,"暂停施工","");
        return MapUtil.mapper("success",true);
    }

    public ServicePlan servicePlanItemWorkState(MaintenanceOrder maintenanceOrder,ServicePlan servicePlan,String state,boolean isUpdate) {
        for (ServicePlanItem servicePlanItem : servicePlan.getServicePlanItems()) {
            if (servicePlanItem.getId().equals(maintenanceOrder.getServicePlanItem().getId())){
                if (!Objects.isNull(servicePlanItem.getParentServicePlanItem())){
                    servicePlanItem.getParentServicePlanItem().setWorkState(state);
                }
                if (state.equals("termination")) servicePlanItem.setState("termination");
                servicePlanItem.setWorkState(state);
            }
        }
        if (isUpdate){
            return servicePlanceService.updateOnly(servicePlan);
        }else{
            return servicePlan;
        }
    }

    public void publish(String payload, String id) {
        OutboxPayloadWrapper wrapper = new OutboxPayloadWrapper();
        wrapper.setSubscriber("local.MaintenanceVoucherService.createVoucher");
        wrapper.setPayload(payload);
        wrapper.setAggregateId(id);
        SpringManager.getBean(OutboxEventService.class).sendSaveEvent(wrapper);
    }

    /**
     * 从来框架查询服务工单
     * @param request
     * @return
     */
    public Map qryMaintenanceFromOld(SimpleRequest request){
        JSONObject jo = request.getJO();
        int startPage = (jo.getInteger("page") - 1) * jo.getInteger("size") + 1;
        int endPage = jo.getInteger("page") * jo.getInteger("size");
        JSONObject tjJson = new JSONObject();
        JSONArray conditionArray = (JSONArray)jo.get("condition");

        conditionArray.stream().forEach(item ->{
            JSONObject json = (JSONObject)item;
            if(json.getString("field").equals("ZDRQ_SJ")){
                if(json.getString("operator").equals("GTE")){ //开始
                    tjJson.put("ZDRQ_SJ_START",json.getString("value"));
                }else { //结束
                    tjJson.put("ZDRQ_SJ_END",json.getString("value"));
                }
            }else if(json.getString("field").equals("MDID")){
                try {
                    tjJson.put(json.getString("field"),SpringManager.getBean(DeptRepository.class).findOne(json.getString("value")).getOrigin());
                }catch (Exception e){
                    throw new RuntimeException("获取外部门店编码失败");
                }
            }else{
                tjJson.put(json.getString("field"),json.getString("value"));
            }

        });
        Object obj = piManager.synErp("ipmServicePlanService.qryNXFWGDH", MapUtil.mapper(
                "CPHM",tjJson.getString("CPHM"),
                "FWFAH",tjJson.getString("FWFAH"),
                "ZDRQ_SJ_START",tjJson.getString("ZDRQ_SJ_START"),
                "ZDRQ_SJ_END",tjJson.getString("ZDRQ_SJ_END"),
                "MDID",tjJson.getString("MDID"),
                "DJZT",tjJson.getString("DJZT"),
                "STARTNUMBER",startPage,
                "ENDNUMBER",endPage,
                "page",jo.getInteger("page"),
                "size",jo.getInteger("size")
        ));
        JSONObject json = JSONObject.parseObject((String) ((JSONObject) obj).get("obj"));

        return MapUtil.mapper(
                "total",json.get("total"),
                "pages",json.get("pages"),
                "size",jo.getInteger("size"),
                "elements",json.get("elements"),
                "page",jo.getInteger("page"),
                "content",json.get("content")
        );
    }

    /**
     * 获取质检数
     * @param simpleRequest
     * @return
     */
    public Map qualityTestAmount(SimpleRequest simpleRequest){
        Dept dept = MapUtil.getO(simpleRequest.getJO().getJSONObject("dept"), Dept.class);
        Map map = findWaitQualityTestAmountServicePlan(findWaitQualityTestAmountServicePlan(dept));
        return MapUtil.mapper(
                "qty",map.size()
        );
    }

    /**
     * 恢复施工
     * @param simpleRequest
     * @return
     */
    public Map renewConstruction(SimpleRequest simpleRequest){
        MaintenanceOrder originMaintenanceOrder = simpleRequest.getO(MaintenanceOrder.class);
        MaintenanceOrder maintenanceOrder = maintenanceOrderRepository.findOne(originMaintenanceOrder.getId());
        maintenanceOrder.setOperator1(originMaintenanceOrder.getOperator1());
        if(!MaintenanceOrder.WORK_ORDER_WORKSTATE_PAUSE.equals(maintenanceOrder.getWorkState()))
            throw new RuntimeException("请检查工单的状态，不处于暂停状态");

        if(maintenanceOrder != null && maintenanceOrder.getFinishDate() != null) throw new RuntimeException("该工单不处于暂停中，无需暂停");

        //施工写记录
        ConstructionRecord constructionRecord
                = constructionRecordService.constructionRecord(maintenanceOrder,ConstructionRecord.CONST_TABLE_OPERATETYPE_RENEW,"");
        this.invoke("fn.constructRecord.createOrUpdate",MapUtil.mapped(constructionRecord));

        maintenanceOrder.setWorkState(MaintenanceOrder.WORK_ORDER_WORKSTATE_WORKING);
        calcutelateTimeNow(constructionRecord,maintenanceOrder);
        servicePlanItemWorkState(maintenanceOrder,maintenanceOrder.getServicePlanItem().getServicePlan(),"working",true);
        maintenanceOrder = maintenanceOrderRepository.saveAndFlush(maintenanceOrder);
        return MapUtil.mapper("success",true);
    }

    /**
     * 递归回写过程
     * @param maintenanceOrder
     * @return
     */
    public MaintenanceOrder reWriteBackData(MaintenanceOrder maintenanceOrder,String type){
//        reWriteBackDataLogger(maintenanceOrder,type); // 记录日志
        MaintenanceOrder originMaintenanceOrder= findOrigin(maintenanceOrder);
        if(originMaintenanceOrder != null){
            switch (type){
                case "finish":
                    finishMaintenance(originMaintenanceOrder,maintenanceOrder);
                    break;
                case "outFinish":
                    outFinishReWrite(originMaintenanceOrder,maintenanceOrder);
                    break;
                case "outTermination":
                    outTerminationReWrite(originMaintenanceOrder,maintenanceOrder);
                    break;
                default:
                    throw new RuntimeException("无效操作码");
            }
            reWriteBackData(originMaintenanceOrder,type);
        }
        //处理工单对应的方案
        switch (type){
            case "finish":
                commonFinishServicePlan(maintenanceOrder);
                break;
            case "outFinish":
                outFinishSerivcePlan(maintenanceOrder);
                break;
            case "outTermination":
                outTerminationSerivcePlan(maintenanceOrder);
                break;
            default:
                throw new RuntimeException("无效操作码");
        }
        return save(maintenanceOrder);
    }
    /**
     * 递归回写过程(只回写工单)钣喷完工调用
     * @param maintenanceOrder
     * @return
     */
    public MaintenanceOrder onlyReWriteBackData(MaintenanceOrder maintenanceOrder,String type){
//        reWriteBackDataLogger(maintenanceOrder,type); // 记录日志
        MaintenanceOrder originMaintenanceOrder= findOrigin(maintenanceOrder);
        if(originMaintenanceOrder != null){
            switch (type){
                case "finish":
                    finishMaintenance(originMaintenanceOrder,maintenanceOrder);
                    break;
                case "outFinish":
                    outFinishReWrite(originMaintenanceOrder,maintenanceOrder);
                    break;
                case "outTermination":
                    outTerminationReWrite(originMaintenanceOrder,maintenanceOrder);
                    break;
                default:
                    throw new RuntimeException("无效操作码");
            }
            onlyReWriteBackData(originMaintenanceOrder,type);
        }
        return save(maintenanceOrder);
    }
//    /**
//     * 递归回写过程(回写方案明细) 钣喷完工调用
//     * @param maintenanceOrder
//     * @return
//     */
//    public MaintenanceOrder onlyReWriteBackServicePlanItemsFinishData(MaintenanceOrder maintenanceOrder){
//        //更新对应方案明细，设置完成状态
//        String state = "treatQuality";
//        ServicePlanItem servicePlanItem = maintenanceOrder.getServicePlanItem();
//        servicePlanItem.setFinishDate(new Date());
//        if (!Objects.isNull(servicePlanItem.getParentServicePlanItem())){
//            servicePlanItem.getParentServicePlanItem().setWorkState(state);
//        }
//        servicePlanItem.setWorkState(state);
//        servicePlanItemRepository.saveAndFlush(servicePlanItem);
//        return maintenanceOrder;
//    }
//    public void onlyReWriteBackServicePlanFinishData(ServicePlan servicePlan){
//
//        // 检查是否整单完成
//        if("finish".equals(servicePlan.checkResultByItem())){
//            servicePlan.setFinishWork(true);
//        };
//        servicePlanceService.updateOnly(servicePlan);
//        servicePlanceService.confirmToApp(servicePlan);
//    }


    /**
     * 保存操作
     * @param maintenanceOrder
     * @return
     */
    public MaintenanceOrder save(MaintenanceOrder maintenanceOrder){
        return maintenanceOrderRepository.saveAndFlush(maintenanceOrder);
    }

    public Map structureMaintenanceByServicePlan(ServicePlan servicePlan,String type,boolean isHasInnerDept){
        List<MaintenanceOrder> maintenanceOrders = new ArrayList<>();
        servicePlan.getServicePlanItems().forEach((servicePlanItem)->{
            if(servicePlanItem.returnMaintenanceOrder() != null) maintenanceOrders.add(servicePlanItem.returnMaintenanceOrder());
        });

        //检测是否有可转内协商品
        List list = maintenanceOrders.stream().filter(maintenanceOrder -> MaintenanceOrder.CONST_TABLE_STATE_CREATE.equals(maintenanceOrder.getState())).collect(Collectors.toList());

        //检测是否有可转内协商品
        List workState = maintenanceOrders.stream().filter(maintenanceOrder -> !MaintenanceOrder.WORK_ORDER_WORKSTATE_WAIT.equals(maintenanceOrder.getWorkState())).collect(Collectors.toList());
        Map innerDept = new HashMap();
        if (isHasInnerDept && servicePlan.getBelongDept() != null && "toInner".equals(type)) innerDept.put("innerDept", MapUtil.mapped(innerDept(servicePlan.getBelongDept().getId())));
        return MapUtil.mapper(
                "SERVICE_PLAN_ID",servicePlan.getId(),
                "SERVICE_PLAN_STATE",servicePlan.getState(),
                "customerCar",servicePlan.getCustomerCar(),
                "customer",servicePlan.getCustomer(),
                "belongDept",servicePlan.getBelongDept(),
                "inOutFlag", list.size() > 0,
                "workStateFlag", workState.size() > 0,
                "maintenanceOrders",maintenanceOrders.stream().map(maintenanceOrder -> {
                    Map m = MapUtil.mapped(maintenanceOrder);
                    if ((double)m.get("platformPriceCosInTaxTemp")==0D) {
                        m.remove("platformPriceCosInTaxTemp");
                    }
                    Map mapped = MapUtil.mapped(maintenanceOrder.getServicePlanItem());
                    mapped.put("serveType",maintenanceOrder.getServicePlanItem().getProduct().getServeType());
                    if ("toOut".equals(type))m.put("outAssistType","inPlatform");
                    m.put("servicePlanItem",mapped);
                    m.put("innerDept",innerDept.get("innerDept"));
                    return m;
                }).toArray()
        );
    }

    private Dept innerDept(String deptId){
        JSONArray ja = servicePlanDao.queryRecentlyInner(new JSONObject(MapUtil.mapper("deptId", deptId)));
        if (ja.isEmpty()) return null;
        JSONObject jo = (JSONObject) ja.get(0);
        String innerDeptId = jo.getString("BELONG_DEPT_ID");
        return SpringManager.getBean(DeptRepository.class).findOne(innerDeptId);
    }

    /**
     * 修改工单施工人员
     * @param simpleRequest
     * @return
     */
    private Map updataWorker(SimpleRequest simpleRequest){
        JSONObject request = simpleRequest.getJO();
        if("receivables".equals(request.getString("SERVICE_PLAN_STATE"))) throw new RuntimeException("当前方案状态不允许修改施工人员");
        List<ServicePlan> servicePlans = servicePlanRepository.findAll(JpaDsl.toCriteriaByEq("id",request.getString("SERVICE_PLAN_ID")));
        ServicePlan servicePlan = servicePlans.get(0);
        if (!servicePlan.getState().equals(request.getString("SERVICE_PLAN_STATE"))) throw new RuntimeException("方案状态发生改变,请刷新页面");

        List<MaintenanceOrder> maintenanceOrders =
                maintenanceOrdersTransfer(simpleRequest.getJO().getJSONArray("maintenanceOrders"));
        //过滤未选中
        List<MaintenanceOrder> maintenanceOrderList = maintenanceOrders.stream().filter(MaintenanceOrder::isSelected).collect(Collectors.toList());

        if (maintenanceOrderList.size()==0) throw new RuntimeException("请勾选需要修改施工人员的商品");

        maintenanceOrderList = maintenanceOrderList.stream().map(maintenanceOrder -> {
            if(maintenanceOrder.getWorkState().equals("wait"))return maintenanceOrder;
            maintenanceOrder.setWorker1Show(maintenanceOrder.changeWorkerToWorkerShow(maintenanceOrder.getWorker1()));
            maintenanceOrder.setWorker2Show(maintenanceOrder.changeWorkerToWorkerShow(maintenanceOrder.getWorker2()));
            maintenanceOrder.setWorker3Show(maintenanceOrder.changeWorkerToWorkerShow(maintenanceOrder.getWorker3()));
            maintenanceOrder.setWorker4Show(maintenanceOrder.changeWorkerToWorkerShow(maintenanceOrder.getWorker4()));
            return maintenanceOrderRepository.saveAndFlush(maintenanceOrder);
        }).collect(Collectors.toList());
        //被过滤商品重新添加返回工单
        maintenanceOrderList.addAll(maintenanceOrders.stream().filter((maintenanceOrder)->{
            return !maintenanceOrder.isSelected();
        }).map(maintenanceOrder -> {
            return maintenanceOrderRepository.findOne(maintenanceOrder.getId());
        }).collect(Collectors.toList()));
        return MapUtil.mapper(
                "SERVICE_PLAN_ID", servicePlan.getId(),
                "SERVICE_PLAN_STATE", servicePlan.getState(),
                "customerCar", servicePlan.getCustomerCar(),
                "customer", servicePlan.getCustomer(),
                "belongDept", servicePlan.getBelongDept(),
                "inOutFlag",request.getBoolean("inOutFlag"),
                "workStateFlag",request.getBoolean("workStateFlag"),
                "maintenanceOrders",maintenanceOrderList.stream().map(maintenanceOrder -> {
                    Map m = MapUtil.mapped(maintenanceOrder);
                    if (maintenanceOrder.getWorkState().equals("working")||maintenanceOrder.getWorkState().equals("finish")){
                        m.put("workFlag",true);
                    } else {
                        m.put("workFlag",false);
                    }
                    m.put("servicePlanItem",MapUtil.mapped(maintenanceOrder.getServicePlanItem()));
                    return m;
                }).toArray()
        );
    }

    /**
     * 开始施工
     * @param
     * @return
     */
    public Map startConstruction(SimpleRequest simpleRequest){
        MaintenanceOrder originMaintenanceOrder = simpleRequest.getO(MaintenanceOrder.class);
        MaintenanceOrder maintenanceOrder = maintenanceOrderRepository.findOne(originMaintenanceOrder.getId());
        if(maintenanceOrder == null) throw new RuntimeException("该工单不存在不存在");
        if(maintenanceOrder.isLockState()) throw new RuntimeException("工单在锁定状态，请解锁再开始施工");
        if(!MaintenanceOrder.WORK_ORDER_WORKSTATE_WAIT.equals(maintenanceOrder.getWorkState())) throw new RuntimeException("工单不在待施工状态，无法开始施工");
        if(MaintenanceOrder.CONST_TABLE_STATE_INNER.equals(maintenanceOrder.getState())) throw new RuntimeException("单据内协中无法施工");


        if(maintenanceOrder != null && maintenanceOrder.getFinishDate() != null) return MapUtil.mapper("success",true);


        maintenanceOrder.setParts(originMaintenanceOrder.getParts());
        maintenanceOrder.setOperator1(originMaintenanceOrder.getOperator1());
        maintenanceOrder.setWorker(originMaintenanceOrder.getWorker());

        //1.判断能否开始施工（配件领用，是否处于新增状态.是否处于待施工状态）
        if(!MaintenanceOrder.WORK_ORDER_WORKSTATE_WAIT.equals(maintenanceOrder.getWorkState())) throw new RuntimeException("请检查工单的状态，不处于待施工状态");
        if(originMaintenanceOrder.getParts().size() != 0){
            List<ServicePlanItem> servicePlanItems = originMaintenanceOrder.getParts().stream().filter((servicePlanItem)->{
                return servicePlanItem.getSaleQty() > servicePlanItem.getQtyReceive() + servicePlanItem.getQtyEnd();
            }).collect(Collectors.toList());

            if(servicePlanItems.size() != 0) {
                String tip = "";
                for(ServicePlanItem servicePlanItem : servicePlanItems){
                    tip = tip +servicePlanItem.getProduct().getName()+ "/";
                }
                throw new RuntimeException("以下商品未完成领料，不可完成施工,商品编码：" + tip);
            }
        }
        //施工写记录
        ConstructionRecord constructionRecord
                = constructionRecordService.constructionRecord(maintenanceOrder,ConstructionRecord.CONST_TABLE_OPERATETYPE_START,"");
        constructionRecord = this.invoke("fn.constructRecord.createOrUpdate",MapUtil.mapped(constructionRecord));
        //2.绑定配件
        bindPartsToWorkInner(maintenanceOrder);
        //更新当前工单状态
        maintenanceOrder.setWorkState(MaintenanceOrder.WORK_ORDER_WORKSTATE_WORKING);
        try {
            maintenanceOrder.setWorker1(JSON.toJSONString(originMaintenanceOrder.getWorker().stream().map((partyRole)->{
                PartyRole role = partyRoleRepository.findOne(partyRole.getId());
                return MapUtil.mapper("id",role.getId(),"name",role.getName());
            }).collect(Collectors.toList())));
        } catch (Exception e) {
            throw new RuntimeException("请检查人员编码是否存在");
        }
        maintenanceOrder.setWorker1Show(maintenanceOrder.changeWorkerToWorkerShow(maintenanceOrder.getWorker1()));
        calcutelateTimeNow(constructionRecord,maintenanceOrder);
        maintenanceOrder = maintenanceOrderRepository.saveAndFlush(maintenanceOrder);
        ServicePlan servicePlan = maintenanceOrder.getServicePlanItem().getServicePlan();
        if (maintenanceOrderRepository.findWorkindByServicePlan(servicePlan.getId()).size()==1) {
            servicePlanceService.addServicePlanLogger(servicePlan,"开始施工","");
        }
        // 方案明细状态
        servicePlanItemWorkState(maintenanceOrder, servicePlan, "working",true);
        //更新当前工单状态
        return MapUtil.mapper("success",true);
    }



    public List<Enumeration> suspendReason(SimpleRequest simpleRequest){
        Sort sort = new Sort(Sort.Direction.ASC, "code");   //根据显示编码进行降序排序
        List<Enumeration> enumerations = enumerationRepository.findAll(
                JpaDsl.toCriteria("type.id","EQ",simpleRequest.getJO().getString("type")),sort
        );
        return enumerations;
    }

    /**
     *同步工单
     * @param simpleRequest
     * @return
     */
    public List synMaintenanceOrder(SimpleRequest simpleRequest){
        JSONObject jsonObject = simpleRequest.getJO();
        String id = jsonObject.getString("id");
        int maxNum = jsonObject.getInteger("maxNum");
        Date date = new Date(jsonObject.getLong("timestamp"));
        List<MaintenanceOrder> list = maintenanceOrderRepository.synMaintenanceOrder(date, id, PageRequest.of(0, maxNum));
//        List resultList = list.stream().map(maintenanceOrder -> {
//            return MapUtil.mapper(
//                    "id",maintenanceOrder.getId(),
//                    "state",maintenanceOrder.getState(),
//                    "lockState",maintenanceOrder.isLockState(),
//                    "businessType",maintenanceOrder.getBusinessType(),
//                    "businessTypeName",maintenanceOrder.getBusinessTypeName(),
//                    "sourceBusinessType",maintenanceOrder.getServicePlanItem().getServicePlan().getSourceBusinessType(),
//                    "sourceFrom",maintenanceOrder.getServicePlanItem().getServicePlan().getSourceFrom(),
//                    "belongDept",maintenanceOrder.getBelongDept(),
//                    "fnCustomerExpand",maintenanceOrder.getFnCustomerExpand(),
//                    "remark","",
//                    "finishDate",maintenanceOrder.getFinishDate(),
//                    "terminationDate",maintenanceOrder.getTerminationDate(),
//                    "company",maintenanceOrder.getBelongDept().getCompany(),
//                    "creator",maintenanceOrder.getCreator() == null ? null : partyRoleRepository.findOne(maintenanceOrder.getCreator()),
//                    "createDate",maintenanceOrder.getCreateDate(),
//                    "lastUpdatedStamp", DateUtil.timeStampToStr(maintenanceOrder.getLastUpdatedStamp().getTime()),
//                    "receivablesFlag",maintenanceOrder.getServicePlanItem().getServicePlan().getReceivableDate() == null ? false : true,
//                    "version",maintenanceOrder.getVersion()
//            );
//        }).collect(Collectors.toList());
        return list;
    }

    /**
     *同步工单
     * @param simpleRequest
     * @return
     */
    public MaintenanceOrder synMaintenanceOrderById(SimpleRequest simpleRequest){
        JSONObject jsonObject = simpleRequest.getJO();
        String id = jsonObject.getString("id");
        return maintenanceOrderRepository.findOne(id);
    }

    /**
     *同步工单
     * @param simpleRequest
     * @return
     */
    public List synMaintenanceOrderByServicePlanId(SimpleRequest simpleRequest){
        JSONObject jsonObject = simpleRequest.getJO();
        String id = jsonObject.getString("id");
        List<MaintenanceOrder> list = maintenanceOrderRepository.findAll(JpaDsl.toCriteriaByEq("servicePlanItem.servicePlan.id",id));
        return list;
    }


    /**
     * 待质检队列
     * @param simpleRequest
     * @return
     */
    public Map waitQualityTest(SimpleRequest simpleRequest){
        int page = simpleRequest.getJO().getInteger("page");
        int size = simpleRequest.getJO().getInteger("size");

        JSONObject json = new JSONObject();
        json.put("DEPTID",simpleRequest.getJO().getJSONObject("dept").getString("id"));
        JSONArray waitArray = servicePlanDao.waitQualityTest(json);

        List<JSONObject> pxList = new ArrayList();
        //根据车牌分组
        waitArray.stream().collect(groupingBy(item->{
            return ((JSONObject)item).getString("FN_CUSTOMER_EXPAND_ID");
        })).forEach((k,v)->{
            JSONArray vArray = new JSONArray(v);

            JSONObject esJson = (JSONObject) vArray.stream().filter(item ->{
                return ((JSONObject)item).get("ESTIMATED_DELIVERY_DATE") != null;
            }).max((a,b)->{return ((JSONObject)a).getDate("ESTIMATED_DELIVERY_DATE").getTime() >= ((JSONObject)b).getDate("ESTIMATED_DELIVERY_DATE").getTime() ? 1 : -1 ;}).orElse(null);


            JSONObject waitTimeJson = (JSONObject) vArray.stream().filter(item ->{
                return ((JSONObject)item).get("FINISH_DATE") != null;
            }).max((a,b)->{return ((JSONObject)a).getDate("FINISH_DATE").getTime() >= ((JSONObject)b).getDate("FINISH_DATE").getTime() ? 1 : -1 ;}).orElse(null);
            Date finishDate = waitTimeJson == null ? new Date() : waitTimeJson.getDate("FINISH_DATE");
            JSONObject vJson = new JSONObject();
            vJson.put("fnCustomerExpand",MapUtil.mapper("id",vArray.getJSONObject(0).getString("FN_CUSTOMER_EXPAND_ID"),"carLicense",vArray.getJSONObject(0).getString("CAR_LICENSE"),"carModelLabel",vArray.getJSONObject(0).getString("CAR_MODEL_LABEL")));
            vJson.put("estimateTime",esJson == null ? null : esJson.getDate("ESTIMATED_DELIVERY_DATE"));
            vJson.put("waitTime",(int)((new Date().getTime() - finishDate.getTime())/1000));
            vJson.put("pickUpCarId",vArray.getJSONObject(0).getString("PICK_UP_ID"));
            vJson.put("planList",vArray.stream().collect(groupingBy(itemP ->{return ((JSONObject)itemP).getString("SERVICE_PLAN_ID");})).keySet());

            List list = new ArrayList();
            JSONObject machineRepaMap = new JSONObject();
            machineRepaMap.put("style","machineRepa");
            machineRepaMap.put("qty",0);
            JSONObject cosmetologyMap = new JSONObject();
            cosmetologyMap.put("style","cosmetology");
            cosmetologyMap.put("qty",0);
            JSONObject sprayPaintMap = new JSONObject();
            sprayPaintMap.put("style","sprayPaint");
            sprayPaintMap.put("qty",0);
            list.add(machineRepaMap);
            list.add(cosmetologyMap);
            list.add(sprayPaintMap);

            vArray.stream().collect(groupingBy(item->{
                JSONObject itemJson = (JSONObject)item;
                String style = "007".equals(itemJson.getString("SERVE_TYPE_ID")) ? "sprayPaint" :
                        ("001".equals(itemJson.getString("SERVE_TYPE_ID")) || "002".equals(itemJson.getString("SERVE_TYPE_ID"))) ? "cosmetology": "machineRepa"; //默认机修
                return itemJson.getString("SERVICE_PLAN_ID") + "---...---"+ style;
            })).forEach((x,y)->{
                String[] strs = x.split("---...---");
                if("sprayPaint".equals(strs[1])){ //钣喷
                    sprayPaintMap.put("qty",sprayPaintMap.getDoubleValue("qty") + 1);
                }else if("cosmetology".equals(strs[1])){//美容
                    cosmetologyMap.put("qty",cosmetologyMap.getDoubleValue("qty") + 1);
                }else{ //机修
                    machineRepaMap.put("qty",machineRepaMap.getDoubleValue("qty") + 1);
                }
            });
            vJson.put("styleItems",list);
            pxList.add(vJson);
        });
        Collections.sort(pxList, new Comparator<JSONObject>() {
            @Override
            public int compare(JSONObject o1, JSONObject o2) {
                return o1.getDate("waitTime").getTime() >= o2.getDate("waitTime").getTime() ? -1 : 1;
            }
        });

        List pxResultList = new ArrayList();
        //list 根据等待时间进行一个排序
        //根据分页返回
        int begin = (page - 1) * size ;
        int end = page * size;
        for(int i = 0;i<pxList.size();i++){
            if(i < end && i>= begin){
                pxResultList.add(pxList.get(i));
            }
        }
        return MapUtil.mapper(
                "page",page,
                "size",size,
                "total",pxList.size(),
                "items",pxResultList
        );
    }

    /**
     * 质检明细
     * @param simpleRequest
     * @return
     */
    public Map waitQualityTestDetail(SimpleRequest simpleRequest){
        FnCustomerExpand fnCustomerExpand = SpringManager.getBean(FnCustomerExpandRepository.class).findOne(simpleRequest.getJO().getJSONObject("fnCustomerExpand").getString("id"));
        JSONObject param = new JSONObject();
        param.put("FN_CUSTOMER_EXPAND_ID",fnCustomerExpand.getId());
        param.put("DEPT_ID",simpleRequest.getJO().getJSONObject("dept").getString("id"));

        JSONArray detailArray = servicePlanDao.waitQualityTestDetail(param);
        if(detailArray.isEmpty()){

            JSONArray productReceives = servicePlanDao.findPlanItemForProductReceive(param);
            if (!productReceives.isEmpty()) {
                throw new RuntimeException("存在未领用的配件，请检查");
            } else {
                throw new RuntimeException("质检队列发生变化，请重新刷新");
            }
        }

        //获取工时绑定的配件
        JSONArray workDetailM2S = servicePlanDao.workDetailM2S(param);

        List list = new ArrayList();
        JSONObject machineRepaMap = new JSONObject();
        machineRepaMap.put("style","machineRepa");
        machineRepaMap.put("qty",0);
        List machineRepaMapArray = new ArrayList();
        machineRepaMap.put("servicePlanItems",machineRepaMapArray);

        JSONObject cosmetologyMap = new JSONObject();
        cosmetologyMap.put("style","cosmetology");
        cosmetologyMap.put("qty",0);
        List cosmetologyMapArray = new ArrayList();
        cosmetologyMap.put("servicePlanItems",cosmetologyMapArray);

        cosmetologyMap.put("servicePlanItems",cosmetologyMapArray);
        JSONObject sprayPaintMap = new JSONObject();
        sprayPaintMap.put("style","sprayPaint");
        sprayPaintMap.put("qty",0);
        List sprayPaintMapArray = new ArrayList();
        sprayPaintMap.put("servicePlanItems",sprayPaintMapArray);

        list.add(machineRepaMap);
        list.add(cosmetologyMap);
        list.add(sprayPaintMap);
        detailArray.stream().collect(groupingBy(item->{
            JSONObject itemJson = (JSONObject)item;
            String style = "007".equals(itemJson.getString("SERVE_TYPE_ID")) ? "sprayPaint" :
                    ("001".equals(itemJson.getString("SERVE_TYPE_ID")) || "002".equals(itemJson.getString("SERVE_TYPE_ID"))) ? "cosmetology": "machineRepa"; //默认机修
            return itemJson.getString("SERVICE_PLAN_ID") + "---...---"+ style;
        })).forEach((x,y)->{
            String[] strs = x.split("---...---");
            JSONArray yArray = new JSONArray(y);
            JSONObject itemJson = new JSONObject();
            itemJson.put("workItems",yArray.stream().map(workJson ->{
                JSONObject workJsonTemp = (JSONObject)workJson;
                List workList = new ArrayList();
                if(workJsonTemp.getString("WORKER1_M") != null) workList.addAll(JSONArray.parseArray(workJsonTemp.getString("WORKER1_M"),HashMap.class));
                if(workJsonTemp.getString("WORKER2_M") != null) workList.addAll(JSONArray.parseArray(workJsonTemp.getString("WORKER2_M"),HashMap.class));
                if(workJsonTemp.getString("WORKER3_M") != null) workList.addAll(JSONArray.parseArray(workJsonTemp.getString("WORKER3_M"),HashMap.class));
                if(workJsonTemp.getString("WORKER4_M") != null) workList.addAll(JSONArray.parseArray(workJsonTemp.getString("WORKER4_M"),HashMap.class));

                return MapUtil.mapper("id",workJsonTemp.getString("SERVICE_PLAN_ITEM_ID"),
                        "finishDate",workJsonTemp.getDate("FINISH_DATE"),
                        "product",MapUtil.mapper("id",workJsonTemp.getString("PRODUCT_ID"),"name",workJsonTemp.getString("PRODUCT_NAME")),
                        "partsItems",workDetailM2S.stream().filter(m2sJson->{
                            JSONObject m2sJsonT = (JSONObject)m2sJson;
                            return m2sJsonT.getString("SERVICE_PLAN_ITEM_P").equals(workJsonTemp.getString("SERVICE_PLAN_ITEM_ID"));
                        }).map(m2sJson ->{
                            JSONObject m2sJsonT = (JSONObject)m2sJson;
                            return MapUtil.mapper("id",m2sJsonT.getString("SERVICE_PLAN_ITEM"),"saleQty",m2sJsonT.getDoubleValue("SALE_QTY") - m2sJsonT.getDoubleValue("QTY_END"),"product",MapUtil.mapper("id",m2sJsonT.getString("PRODUCT_ID"),"name",m2sJsonT.getString("PRODUCT_NAME")));
                        }).collect(Collectors.toCollection(JSONArray::new)),
                        "worker",workList);
            }).collect(Collectors.toList()));

            JSONObject maxJson = (JSONObject) yArray.stream().filter(itemMax ->{
                JSONObject itemMaxTemp = (JSONObject)itemMax;
                return itemMaxTemp.get("FINISH_DATE") != null;
            }).max((a, b)->{
                return ((JSONObject)a).getDate("FINISH_DATE").getTime() >= ((JSONObject)b).getDate("FINISH_DATE").getTime()  ? -1 : 1;
            }).get();

            itemJson.put("maxFinishDate",maxJson == null ? null : maxJson.getDate("FINISH_DATE"));
            itemJson.put("qualityTestUid",MapUtil.mapper("id",yArray.getJSONObject(0).getString("QUALITY_TEST_UID"),"name",yArray.getJSONObject(0).getString("QUALITY_TEST_U_NAME")));
            itemJson.put("qualityTestDate",yArray.getJSONObject(0).getDate("QUALITY_TEST_DATE"));
            itemJson.put("id",strs[0]);
            itemJson.put("state",yArray.getJSONObject(0).get("QUALITY_TEST_DATE") == null ? "waitQualityTest" :
                            yArray.getJSONObject(0).getBoolean("QUALITY_FLAG") == true ?  "standard" : "unstandard");

            if("sprayPaint".equals(strs[1])){ //钣喷
                sprayPaintMap.put("qty",sprayPaintMap.getDoubleValue("qty") + 1);
                sprayPaintMapArray.add(itemJson);
                itemJson.put("style","sprayPaint");
            }else if("cosmetology".equals(strs[1])){//美容
                cosmetologyMap.put("qty",cosmetologyMap.getDoubleValue("qty") + 1);
                cosmetologyMapArray.add(itemJson);
                itemJson.put("style","cosmetology");
            }else{ //机修
                machineRepaMap.put("qty",machineRepaMap.getDoubleValue("qty") + 1);
                machineRepaMapArray.add(itemJson);
                itemJson.put("style","machineRepa");
            }
        });

        Comparator cpt = new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                JSONObject o1Josn = (JSONObject)o1;
                JSONObject o2Josn = (JSONObject)o2;
                return o1Josn.get("maxFinishDate") == null ? 1 :
                        o2Josn.get("maxFinishDate") == null ? -1 :
                                o1Josn.getDate("maxFinishDate").getTime() >= o2Josn.getDate("maxFinishDate").getTime() ? -1 : 1;
            }
        };
        machineRepaMapArray.sort(cpt);
        cosmetologyMapArray.sort(cpt);
        sprayPaintMapArray.sort(cpt);

        List allListsItem = new ArrayList();
        allListsItem.addAll(machineRepaMapArray);
        allListsItem.addAll(cosmetologyMapArray);
        allListsItem.addAll(sprayPaintMapArray);
        allListsItem.sort(cpt);
        JSONObject allLists = new JSONObject();
        allLists.put("qty",allListsItem.size());
        allLists.put("items",allListsItem);

        return MapUtil.mapper(
                "fnCustomerExpand",MapUtil.mapper("id",fnCustomerExpand.getId(), "carLicense", fnCustomerExpand.getCarLicense(), "mobile", fnCustomerExpand.getMobile(),"carModelLabel",fnCustomerExpand.getCarModelLabel()),
                "estimateTime",new Date().getTime(),
                "styles",list,
                "allProducts",allLists
        );
    }

    /**
     * 质检明细(按车辆维度)
     * @param simpleRequest
     * @return
     */
    public Map waitQualityTestPlanDetail(SimpleRequest simpleRequest){
        FnCustomerExpand fnCustomerExpand = SpringManager.getBean(FnCustomerExpandRepository.class).findOne(simpleRequest.getJO().getJSONObject("fnCustomerExpand").getString("id"));
        JSONObject param = new JSONObject();
        param.put("FN_CUSTOMER_EXPAND_ID",fnCustomerExpand.getId());
        param.put("DEPT_ID",simpleRequest.getJO().getJSONObject("dept").getString("id"));

        JSONArray detailArray = servicePlanDao.waitQualityTestDetail(param);
        if(detailArray.isEmpty()) {
            JSONArray productReceives = servicePlanDao.findPlanItemForProductReceive(param);
            if (!productReceives.isEmpty()) {
                throw new RuntimeException("存在未领用的配件，请检查");
            } else {
                throw new RuntimeException("质检队列发生变化，请重新刷新");
            }
        }

        //获取工时绑定的配件
        JSONArray workDetailM2S = servicePlanDao.workDetailM2S(param);

        List list = new ArrayList();
        JSONObject machineRepaMap = new JSONObject();
//        machineRepaMap.put("style","machineRepa");
        machineRepaMap.put("qty",0);
        List machineRepaMapArray = new ArrayList();
        machineRepaMap.put("servicePlanItems",machineRepaMapArray);

        list.add(machineRepaMap);
        detailArray.stream().collect(groupingBy(item->{
            JSONObject itemJson = (JSONObject)item;
            return itemJson.getString("FN_CUSTOMER_EXPAND_ID");
        })).forEach((x,y)->{
            JSONArray yArray = new JSONArray(y);
            JSONObject itemJson = new JSONObject();
            itemJson.put("workItems",yArray.stream().map(workJson ->{
                JSONObject workJsonTemp = (JSONObject)workJson;
                List workList = new ArrayList();
                if(workJsonTemp.getString("WORKER1_M") != null) workList.addAll(JSONArray.parseArray(workJsonTemp.getString("WORKER1_M"),HashMap.class));
                if(workJsonTemp.getString("WORKER2_M") != null) workList.addAll(JSONArray.parseArray(workJsonTemp.getString("WORKER2_M"),HashMap.class));
                if(workJsonTemp.getString("WORKER3_M") != null) workList.addAll(JSONArray.parseArray(workJsonTemp.getString("WORKER3_M"),HashMap.class));
                if(workJsonTemp.getString("WORKER4_M") != null) workList.addAll(JSONArray.parseArray(workJsonTemp.getString("WORKER4_M"),HashMap.class));
//            itemJson.put("id",yArray.getJSONObject(0).get("SERVICE_PLAN_ID"));
                return MapUtil.mapper("id",workJsonTemp.getString("SERVICE_PLAN_ITEM_ID"),
                        "finishDate",workJsonTemp.getDate("FINISH_DATE"),
                        "planId",workJsonTemp.getString("SERVICE_PLAN_ID"),
                        "product",MapUtil.mapper("id",workJsonTemp.getString("PRODUCT_ID"),"name",workJsonTemp.getString("PRODUCT_NAME")),
                        "partsItems",workDetailM2S.stream().filter(m2sJson->{
                            JSONObject m2sJsonT = (JSONObject)m2sJson;
                            return m2sJsonT.getString("SERVICE_PLAN_ITEM_P").equals(workJsonTemp.getString("SERVICE_PLAN_ITEM_ID"));
                        }).map(m2sJson ->{
                            JSONObject m2sJsonT = (JSONObject)m2sJson;
                            return MapUtil.mapper("id",m2sJsonT.getString("SERVICE_PLAN_ITEM"),"saleQty",m2sJsonT.getDoubleValue("SALE_QTY") - m2sJsonT.getDoubleValue("QTY_END"),"product",MapUtil.mapper("id",m2sJsonT.getString("PRODUCT_ID"),"name",m2sJsonT.getString("PRODUCT_NAME")));
                        }).collect(Collectors.toCollection(JSONArray::new)),
                        "worker",workList);
            }).collect(Collectors.toList()));

            JSONObject maxJson = (JSONObject) yArray.stream().filter(itemMax ->{
                JSONObject itemMaxTemp = (JSONObject)itemMax;
                return itemMaxTemp.get("FINISH_DATE") != null;
            }).max((a, b)->{
                return ((JSONObject)a).getDate("FINISH_DATE").getTime() >= ((JSONObject)b).getDate("FINISH_DATE").getTime()  ? -1 : 1;
            }).get();

            itemJson.put("maxFinishDate",maxJson == null ? null : maxJson.getDate("FINISH_DATE"));
            itemJson.put("qualityTestUid",MapUtil.mapper("id",yArray.getJSONObject(0).getString("QUALITY_TEST_UID"),"name",yArray.getJSONObject(0).getString("QUALITY_TEST_U_NAME")));
            itemJson.put("qualityTestDate",yArray.getJSONObject(0).getDate("QUALITY_TEST_DATE"));
            itemJson.put("state",yArray.getJSONObject(0).get("QUALITY_TEST_DATE") == null ? "waitQualityTest" :
                            yArray.getJSONObject(0).getBoolean("QUALITY_FLAG") == true ?  "standard" : "unstandard");

            machineRepaMap.put("qty",machineRepaMap.getDoubleValue("qty") + 1);
            machineRepaMapArray.add(itemJson);
//            itemJson.put("style","machineRepa");
        });

        Comparator cpt = new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                JSONObject o1Josn = (JSONObject)o1;
                JSONObject o2Josn = (JSONObject)o2;
                return o1Josn.get("maxFinishDate") == null ? 1 :
                        o2Josn.get("maxFinishDate") == null ? -1 :
                                o1Josn.getDate("maxFinishDate").getTime() >= o2Josn.getDate("maxFinishDate").getTime() ? -1 : 1;
            }
        };
        machineRepaMapArray.sort(cpt);

        List allListsItem = new ArrayList();
        allListsItem.addAll(machineRepaMapArray);
        allListsItem.sort(cpt);
        JSONObject allLists = new JSONObject();
        allLists.put("qty",allListsItem.size());
        allLists.put("items",allListsItem);

        return MapUtil.mapper(
                "fnCustomerExpand",MapUtil.mapper("id",fnCustomerExpand.getId(), "carLicense", fnCustomerExpand.getCarLicense(), "mobile", fnCustomerExpand.getMobile(),"carModelLabel",fnCustomerExpand.getCarModelLabel()),
                "estimateTime",new Date().getTime(),
                "detail",list,
                "allProducts",allLists
        );
    }

    /**
     * 施工详情
     * @param simpleRequest
     * @return
     */
    public Map workDetail(SimpleRequest simpleRequest){

        String fnCustomerExpandId = simpleRequest.getJO().getJSONObject("fnCustomerExpand").getString("id");
        String deptId = simpleRequest.getJO().getJSONObject("dept").getString("id");

        JSONObject param = new JSONObject();
        param.put("FN_CUSTOMER_EXPAND_ID",fnCustomerExpandId);
        param.put("DEPT_ID",deptId);
        param.put("PRODUCT_RULE",1);
        //当前车辆质检和确认的数据
        JSONArray planArray = servicePlanDao.workDetailServiceplan(param);
        JSONArray orderArray = servicePlanDao.workDetailMaintenanceOrder(param);
        if(planArray.size() == 0 || orderArray.size() == 0) {
//            param.put("PRODUCT_RULE",0);
//            JSONArray jsonArray = servicePlanDao.workDetailMaintenanceOrder(param);
//            if(jsonArray.size()>0) throw new RuntimeException("该车辆在该门店不存在施工项目，请到ERP外协工单明细去完成该外协单据。");
            throw new RuntimeException("该车辆在该门店不存在施工项目，请刷新数据");
        }
        JSONArray planArrayCopy = JSONArray.parseArray(planArray.toJSONString())  ;
        JSONArray orderArrayCopy = JSONArray.parseArray(orderArray.toJSONString()) ;
        //拼装车辆信息数据
        JSONObject planFirstJson = (JSONObject) planArray.stream().findFirst().get();

        List workItems = new ArrayList(); //工时数据
        List partsItems = new ArrayList(); //配件数据
        Map carMap = MapUtil.mapper(
                "carLicense",planFirstJson.getString("CAR_LICENSE"),
                "mobile",planFirstJson.getString("MOBILE"),
                "id",planFirstJson.getString("FN_CUSTOMER_EXPAND_ID"));

        //构造工单快数据
        JSONArray m2sArray = servicePlanDao.workDetailM2S(param); //查找工时下所有配件
        //工单数据添加方案相关数据,拼工单数据,拼工单下的配件信息
        orderArrayCopy.forEach(tempJson ->{
            JSONObject item = (JSONObject)tempJson;
            //添加方案数据
            JSONArray planArrayFillter = planArray.stream().filter(palnJson ->{
                return ((JSONObject)palnJson).getString("SERVICE_PLAN_ITEM_ID").equals(item.getString("SERVICE_PLAN_ITEM_M"));
            }).collect(Collectors.toCollection(JSONArray::new));
            if(planArrayFillter == null || planArrayFillter.size() != 1) throw new RuntimeException("数据有误：工单来源不存在或者有多条");
            item.putAll(planArrayFillter.getJSONObject(0));
            //添加该工单下的配件信息
            item.put("items",m2sArray.stream().filter(itemJson->{
                JSONObject iJson = (JSONObject)itemJson;
                return iJson.getString("ID").equals(item.getString("ID_M"));
            }).map(itemJson ->{
                JSONObject iJson = (JSONObject)itemJson;
                return MapUtil.mapper("id",iJson.getString("SERVICE_PLAN_ITEM"),
                        "saleQty",iJson.getDoubleValue("QTY_RECEIVE"),
                        "qtyReceive",iJson.getDoubleValue("QTY_RECEIVE"),
                        "isReceived",iJson.getDoubleValue("QTY_RECEIVE") == iJson.getDoubleValue("SALE_QTY") - iJson.getDoubleValue("QTY_END") ? true :false,
                        "product",MapUtil.mapper("id",iJson.getString("PRODUCT_ID"),"name",iJson.getString("PRODUCT_NAME")));
            }).collect(Collectors.toCollection(JSONArray::new)));
        });
        //分组取数
        orderArrayCopy.stream().collect(groupingBy(item ->{
            JSONObject tempJson = (JSONObject)item;
            return tempJson.getString("SERVICE_PLAN_ID_M");
        })).forEach((k,v)->{
            JSONArray vArray = new JSONArray(v);
            JSONObject vJson = vArray.getJSONObject(0);
            JSONObject mapJson = new JSONObject();
            mapJson.put("id",k);
            ServicePlan servicePlan = servicePlanRepository.findOne(k);
            mapJson.put("deptRemark",servicePlan.getDeptRemark());
            mapJson.put("customerRemarks",servicePlan.getCustomerRemarks());
            mapJson.put("confirmDate",vJson.getDate("CONFIRM_DATE"));
            mapJson.put("workItems",vArray.stream().map(workItem ->{
                JSONObject workTempJson = (JSONObject)workItem;
                List workList = new ArrayList();
                if(workTempJson.getString("WORKER1_M") != null)
                    workList.addAll(JSONArray.parseArray(workTempJson.getString("WORKER1_M"),HashMap.class));
                if(workTempJson.getString("WORKER2_M") != null) workList.addAll(JSONArray.parseArray(workTempJson.getString("WORKER2_M"),HashMap.class));
                if(workTempJson.getString("WORKER3_M") != null) workList.addAll(JSONArray.parseArray(workTempJson.getString("WORKER3_M"),HashMap.class));
                if(workTempJson.getString("WORKER4_M") != null) workList.addAll(JSONArray.parseArray(workTempJson.getString("WORKER4_M"),HashMap.class));

                return MapUtil.mapper("id",workTempJson.getString("ID_M"),
                        "serveType",workTempJson.getString("WORK_PLATFORM_M"),
                        "estimateTime",workTempJson.getInteger("PRODUCT_HOUR_M"),
                        "currentTime",workTempJson.getString("POINT_M") == null  ? 0 :
                                "finish".equals(workTempJson.getString("POINT_M")) || "end".equals(workTempJson.getString("POINT_M")) ? workTempJson.getInteger("WORKED_TIME_M") * 60:
                                        "pause".equals(workTempJson.getString("POINT_M")) && workTempJson.getDate("POINT_START_TIME_M") == null ? 0 :
                                                "pause".equals(workTempJson.getString("POINT_M")) && workTempJson.getDate("POINT_START_TIME_M") != null? (int)((new Date().getTime() - workTempJson.getDate("POINT_START_TIME_M").getTime()) / 1000 ) :
                                                "start".equals(workTempJson.getString("POINT_M")) && workTempJson.getDate("POINT_START_TIME_M") != null ? (workTempJson.getInteger("WORKED_TIME_M") * 60 +  (int)((new Date().getTime() - workTempJson.getDate("POINT_START_TIME_M").getTime()) / 1000)) :
                                                        "start".equals(workTempJson.getString("POINT_M")) && workTempJson.getDate("POINT_START_TIME_M") == null ? workTempJson.getInteger("WORKED_TIME_M") * 60+(int)((new Date().getTime() - workTempJson.getDate("WORK_START_DATE").getTime()) / 1000 ) :  0,
                        "consumeTime",workTempJson.getString("POINT_M") == null  ? 0 : "finish".equals(workTempJson.getString("POINT_M")) || "end".equals(workTempJson.getString("POINT_M")) ? workTempJson.getInteger("WORKED_TIME_M") * 60: 0,
                        "state",workTempJson.getString("WORK_STATE_M"),
                        "dispatchBackDate",workTempJson.getString("DISPATCH_BACK_DATE"),
                        "worker",workList,
                        "product",MapUtil.mapper("id",workTempJson.getString("PRODUCT_ID"),"name",workTempJson.getString("PRODUCT_NAME")),
                        "productRule",workTempJson.getDoubleValue("PRODUCT_RULE") == 0 ? false : true,
                        "outer",workTempJson.getDoubleValue("OUTER") == 0 ? false : true,
                        "items",workTempJson.getJSONArray("items"));
            }).collect(Collectors.toList()));
            workItems.add(mapJson);
        });

        //构造配件块数据

        JSONArray planArrayCopyFillter = planArrayCopy.stream().filter(tempJson ->{
            JSONObject item = (JSONObject)tempJson;
            return "1".equals(item.getString("QTY_MGMT")) && (item.getString("WORK_STATE_M") == null || "wait".equals(item.getString("WORK_STATE_M")));
        }).collect(Collectors.toCollection(JSONArray::new));

        planArrayCopyFillter.forEach(tempJson ->{
            JSONObject item = (JSONObject)tempJson;
            //添加方案数据
            JSONArray orderFillter = orderArray.stream().filter(orderJson ->{
                return ((JSONObject)orderJson).getString("ID_M").equals(item.getString("RELEVANCE_WORK_ORDER"));
            }).collect(Collectors.toCollection(JSONArray::new));

            if(orderFillter.size() != 0) item.putAll(orderFillter.getJSONObject(0));
        });

        planArrayCopyFillter.stream().filter(item ->{
            JSONObject tempJson = (JSONObject)item;
            return tempJson.getString("WORK_STATE_M") == null || "wait".equals(tempJson.getString("WORK_STATE_M"));
        }).collect(groupingBy(item ->{
            JSONObject tempJson = (JSONObject)item;
            return tempJson.getString("SERVICE_PLAN_ID");
        })).forEach((k,v)->{
            JSONArray vArray = new JSONArray(v);
            JSONObject patrsJson  =new JSONObject();
            patrsJson.put("id",k);
            patrsJson.put("items",vArray.stream().map(itemJson ->{
                JSONObject iJson = (JSONObject)itemJson;
                return MapUtil.mapper("productRule",iJson.getBoolean("PRODUCT_RULE"),
                        "id",iJson.getString("SERVICE_PLAN_ITEM_ID"),
                        "saleQty",iJson.getDoubleValue("SALE_QTY") - iJson.getDoubleValue("QTY_END"),
                        "qtyReceive",iJson.getDoubleValue("QTY_RECEIVE"),
                        "product",MapUtil.mapper("id",iJson.getString("PRODUCT_ID"),"name",iJson.getString("PRODUCT_NAME")),
                        "SERVICEPLAN_ID",iJson.getString("SERVICEPLAN_ID"),
                        "SERVICEPLAN_ITEM_ID",iJson.getString("SERVICEPLAN_ITEM_ID"),
                        "PRODUCT_ID",iJson.getString("PRODUCT_ID"),
                        "PRODUCT_NAME",iJson.getString("PRODUCT_NAME"),
                        "BARCODE",iJson.getString("BARCODE"),
                        "LOCATION_ID",iJson.getString("LOCATION_ID"),
                        "LOCATION_NAME",iJson.getString("LOCATION_NAME"),
                        "SALE_QTY",iJson.getDoubleValue("SALE_QTY") - iJson.getDoubleValue("QTY_END"),
                        "QTY_RECEIVE",iJson.getDoubleValue("QTY_RECEIVE"),
                        "QTY_STOCK",iJson.getDoubleValue("QTY_STOCK"),
                        "isReceived",iJson.getDoubleValue("QTY_RECEIVE") == iJson.getDoubleValue("SALE_QTY") - iJson.getDoubleValue("QTY_END") ? true :false
                );
            }).collect(Collectors.toCollection(JSONArray::new)));
            partsItems.add(patrsJson);
        });


        Collections.sort(workItems, new Comparator<JSONObject>() {
            @Override
            public int compare(JSONObject o1, JSONObject o2) {
                return o1.getDate("confirmDate").getTime() < o2.getDate("confirmDate").getTime() ? 1 : -1;
            }
        });

        return MapUtil.mapper("fnCustomerExpand",carMap,
                "partsItems",partsItems,
                "workItems",workItems);
    }

    /**
     *
     * @param
     * @return
     */
    public String selectWorkPlatform(Dept dept,Product product){
        String result = null;
        Store store =
                SpringManager.getBean(StoreService.class).findStoreByDept(dept);
        String serveType = product.queryServeType().getId();
        switch (store.getStoreType().getCode()){
            case "10": //社区店
                if("001".equals(serveType) || "002".equals(serveType)){
                    result =  "cosmetology";
                }else{
                    result = "machineRepa";
                }
                break;
            case "20": //基地
                if(product.getClassify().getId().startsWith("S010501")
                        || product.getClassify().getId().startsWith("S010502")|| product.getClassify().getId().startsWith("S0106")){
                    result = "sprayPaint";
                }else if("001".equals(serveType) || "002".equals(serveType)){
                    result = "cosmetology";
                }else{
                    result = "machineRepa";
                }
                break;
                default:
                    throw new RuntimeException("门店类型非社区店和钣喷基地");
        }
        return result;
    }

    /**
     *
     * @param
     * @return
     */
    public String selectWorkPlatform(Store store, Product product, ServeType serve){
        String result = null;
        String serveType = serve.getId();
        switch (store.getStoreType().getCode()){
            case "10": //社区店
                if("001".equals(serveType) || "002".equals(serveType)){
                    result =  "cosmetology";
                }else{
                    result = "machineRepa";
                }
                break;
            case "20": //基地
                if(product.getClassify().getId().startsWith("S010501")
                        || product.getClassify().getId().startsWith("S010502")|| product.getClassify().getId().startsWith("S0106")){
                    result = "sprayPaint";
                }else if("001".equals(serveType) || "002".equals(serveType)){
                    result = "cosmetology";
                }else{
                    result = "machineRepa";
                }
                break;
                default:
                    throw new RuntimeException("门店类型非社区店和钣喷基地");
        }
        return result;
    }

    /**
     * 终止施工单据
     * @param maintenanceOrders
     * @return
     */
    public List<MaintenanceOrder> terminationMaintenanceOrders(List<MaintenanceOrder> maintenanceOrders){
        maintenanceOrders.stream().forEach((maintenanceOrder)->{
            if(maintenanceOrder.isSelected()){
//                if(!MaintenanceOrder.CONST_TABLE_STATE_CREATE.equals(maintenanceOrder.getState()))
//                    throw new RuntimeException("施工单商品，处于非终止状态：" + maintenanceOrder.getProduct().getName());
                maintenanceOrder.setState(MaintenanceOrder.CONST_TABLE_STATE_TERMINATION);
                maintenanceOrder.setTerminationDate(new Date());
                maintenanceOrder.setTerminationUid(maintenanceOrder.getOperator1());

                if(constructionRecordService.checkHaveStartRecord(maintenanceOrder))
                    this.invoke("fn.constructRecord.createOrUpdate",MapUtil.mapped(constructionRecordService.constructionRecord(maintenanceOrder,ConstructionRecord.CONST_TABLE_OPERATETYPE_END,"")));
            }
        });
        return updateMaintenanceOrders(maintenanceOrders);
    }

    /**
     * 工单转内协
     * @param simpleRequest
     * @return
     */
    public Object toInner(SimpleRequest simpleRequest){
        JSONObject jo = simpleRequest.getJO();
        List<MaintenanceOrder> maintenanceOrders =
                maintenanceOrdersTransfer(jo.getJSONArray("maintenanceOrders"));
        //过滤需要转的商品
        List<MaintenanceOrder> resultLists = maintenanceOrders.stream().filter((maintenanceOrder)->{
            return maintenanceOrder.isSelected() && maintenanceOrder.checkCanInnerOrOut();
        }).collect(Collectors.toList());
        if(resultLists.size() == 0) throw new RuntimeException("请选择有效合适的转内协商品");
        toInnerCheck(resultLists);
        //转的中间，改了原工单和方案的成本。

        //提前更改状态 防止重复发起内协
        resultLists.forEach((maintenanceOrder)->{
            maintenanceOrder.setState(MaintenanceOrder.CONST_TABLE_STATE_INNER);
            maintenanceOrder.setToInnerDate(new Date());
            maintenanceOrder.setToInnerUid(getPerson(simpleRequest));
            maintenanceOrder.setLockState(false);
            maintenanceOrderRepository.saveAndFlush(maintenanceOrder);
        });
        //获取原方案 判断是否定损类型 更新原方案方案类型
        ServicePlan servicePlan = maintenanceOrders.stream().findFirst().get().getServicePlanItem().getServicePlan();
        String sourceFrom = servicePlan.getSourceFrom();
        if (sourceFrom!=null &&sourceFrom.startsWith("DS")){
            servicePlan.setPlanType("lossSomeAssist");
            servicePlanRepository.saveAndFlush(servicePlan);
        }
        maintenanceToInnerNewToNew(servicePlan,resultLists,getPerson(simpleRequest));
//        servicePlan = toInnerNewToNew(resultLists,getPerson(simpleRequest));
        servicePlanceService.addServicePlanLogger(servicePlan,"转内协","");
        //如果入口是方案就返回整个方案
        return servicePlanceService.getCurrentTimeData(servicePlan);
    }

    /**
     * 异步生成新框架
     * @param servicePlan
     * @param resultMap
     * @param role
     */
    private void maintenanceToInnerNewToNew(ServicePlan servicePlan,List<MaintenanceOrder> resultMap,PartyRole role){
        OutboxPayloadWrapper wrapper = new OutboxPayloadWrapper();
        wrapper.setSubscriber("fn.maintenance.toInnerNewToNew");
        wrapper.setAggregateId("toInnerCreate:" + servicePlan.getId());
        try {
            wrapper.setPayload(JSON.toJSONString(MapUtil.mapper(
                    "resultMap",resultMap,
                    "role",role.getId()
            )));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
        SpringManager.getBean(OutboxEventService.class).sendSaveEvent(wrapper);
    }
    @OutboxSubscriber(id="fn.maintenance.toInnerNewToNew", name="工单转内协(生成新框架)")
    public void toInnerNewToNewCreate(OutboxPayloadWrapper outboxPayloadWrapper) {
        JSONObject payloadJson = JSONObject.parseObject(outboxPayloadWrapper.getPayload());

        JSONArray resultMap = payloadJson.getJSONArray("resultMap");
        String roleId = payloadJson.getString("role");
        PartyRole role = partyRoleRepository.findOne(roleId);
        List<MaintenanceOrder> maintenanceOrders =
                resultMap.stream().map(o ->  maintenanceOrderRepository.findOne(((JSONObject)o).getString("id")))
                        .filter(maintenanceOrder -> {
                            ServicePlanItem servicePlanItem = maintenanceOrder.getServicePlanItem();
                           return servicePlanItem.getSaleQty()-servicePlanItem.getQtyEnd()>0 && servicePlanItem.getFinishDate()==null &&servicePlanItem.getQualityTestDate()==null;
                        }).collect(Collectors.toList());
        if (maintenanceOrders.isEmpty())return;
        toInnerNewToNew(maintenanceOrders,role);
    }
    /**
     * 工单转内协异步生成老框架
     * @param
     */
    public void maintenanceToInner(Map resultMap,JSONArray jgArray,List<String> idList,String role,String id){
        OutboxPayloadWrapper wrapper = new OutboxPayloadWrapper();
        wrapper.setSubscriber("fn.maintenance.maintenanceToInner");
        wrapper.setAggregateId("toInner" + id);
        try {
            wrapper.setPayload(JSON.toJSONString(MapUtil.mapper("jgArray",jgArray,
                    "resultMap",resultMap,
                    "idList",idList,
                    "role",role,
                    "id",id
            )));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
        SpringManager.getBean(OutboxEventService.class).sendSaveEvent(wrapper);
    }
    /**
     * 工单转内协异步生成老框架
     * @param
     */
    @OutboxSubscriber(id="fn.maintenance.maintenanceToInner", name="工单转内协(生成老框架)")
    public void maintenanceToInner(OutboxPayloadWrapper outboxPayloadWrapper) {
        JSONObject payloadJson = JSONObject.parseObject(outboxPayloadWrapper.getPayload());
        Optional.ofNullable(payloadJson.get("resultMap")).orElseThrow(() -> new RuntimeException("传入参数有误"));
        Optional.ofNullable(payloadJson.get("jgArray")).orElseThrow(( ) -> new RuntimeException("传入参数有误"));
        Optional.ofNullable(payloadJson.get("idList")).orElseThrow(() -> new RuntimeException("传入参数有误"));
        Optional.ofNullable(payloadJson.get("role")).orElseThrow(( ) -> new RuntimeException("传入参数有误"));
        Optional.ofNullable(payloadJson.get("id")).orElseThrow(( ) -> new RuntimeException("传入参数有误"));

        JSONObject resultMap = payloadJson.getJSONObject("resultMap");
        JSONArray jgArray = payloadJson.getJSONArray("jgArray");
        JSONArray idList = payloadJson.getJSONArray("idList");
        String role = payloadJson.getString("role");
        String id = payloadJson.getString("id");

        JSONObject resultJson = piManager.synErp(
                "ipmServicePlanService.processOldFrameNX", resultMap
        );


        if (resultJson.getBoolean("success") == true) {
            resultJson.put("id",id);
            //异步回写
            resultJson.put("idList",idList);
            resultJson.put("jgArray",jgArray);
            resultJson.put("role",role);
            maintenanceRewrite(resultJson);
        }else {
            throw new RuntimeException("生成老框架方案失败");
        }

    }

    /**
     * 异步回写
     * @param resultJson
     */
    public void maintenanceRewrite(JSONObject resultJson){
        OutboxPayloadWrapper wrapper = new OutboxPayloadWrapper();
        wrapper.setSubscriber("fn.maintenance.maintenanceRewrite");
        wrapper.setAggregateId("rewrite" + resultJson.getString("id"));
        try {
            wrapper.setPayload(JSON.toJSONString(MapUtil.mapper("resultJson",resultJson)));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
        SpringManager.getBean(OutboxEventService.class).sendSaveEvent(wrapper);
    }


    /**
     * 异步回写
     * @param
     */
    @OutboxSubscriber(id="fn.maintenance.maintenanceRewrite", name="工单异步回写")
    public void maintenanceRewrite(OutboxPayloadWrapper outboxPayloadWrapper) {
        JSONObject payloadJson = JSONObject.parseObject(outboxPayloadWrapper.getPayload());
        Optional.ofNullable(payloadJson.get("resultJson")).orElseThrow(() -> new RuntimeException("传入参数有误"));
        JSONObject resultJson = payloadJson.getJSONObject("resultJson");

        JSONArray idList = resultJson.getJSONArray("idList");
        JSONArray jgArray = resultJson.getJSONArray("jgArray");
        String roleId = resultJson.getString("role");

        String sFWFAH = JSONObject.parseObject(resultJson.getString("obj")).getString("FWFAH");

        PartyRole role = partyRoleRepository.findOne(roleId);

        List<MaintenanceOrder> maintenanceOrders = idList.stream().map((id) -> {
            return maintenanceOrderRepository.findOne((String) id);
        }).collect(Collectors.toList());


        maintenanceOrders.forEach((maintenanceOrder)->{
            jgArray.stream().forEach(tempJson ->{
                JSONObject item = new JSONObject((Map) tempJson);
                if(maintenanceOrder.getId().equals(item.getString("uniqueIdentify"))){
                    maintenanceOrder.setPriceCostUnitInTax(item.getDouble("pftPriceUnit"));
                    maintenanceOrder.setPlatformPriceCosInTax(item.getDouble("pftPriceUnit"));
                }
            });
            maintenanceOrder.setState(MaintenanceOrder.CONST_TABLE_STATE_INNER);
            maintenanceOrder.setToInnerDate(new Date());
            maintenanceOrder.setToInnerUid(role);
            maintenanceOrder.setLockState(false);
        });
        List<MaintenanceOrder> newMaintenanceOrders = updateMaintenanceOrders(maintenanceOrders);

        ServicePlan servicePlan = newMaintenanceOrders.stream().findFirst().get().getServicePlanItem().queryServicePlanByItem();
        BusinessAttributeValue businessAttributeValue = businessAttributeValueRepository.findOne("ServicePlanItem.assistType.inner");
        newMaintenanceOrders.forEach((maintenanceOrder)->{
            servicePlan.getServicePlanItems().forEach((servicePlanItem)->{
                if(servicePlanItem.getId().equals(maintenanceOrder.getServicePlanItem().getId())){
                    servicePlanItem.setAssistType(businessAttributeValue);
                    servicePlanItem.setOldFrameSourceFrom(sFWFAH);

                    servicePlanItem.setPriceCostUnitInTax(maintenanceOrder.getPriceCostUnitInTax());
                    servicePlanItem.setPlatformPriceCosInTax(maintenanceOrder.getPlatformPriceCosInTax());
                    servicePlanItem.setReferTax(maintenanceOrder.getPriceCostUnitInTax());
                }
            });
        });
        servicePlan.setOldFrameSourceFrom(sFWFAH);
        servicePlanceService.updateOnly(servicePlan);

    }

        /**
         * 转内协控制
         * @param
         */
    private void toInnerCheck(List<MaintenanceOrder> maintenanceOrders) {
        //一个方案上的工单，只能转一个店
        Map map = maintenanceOrders.stream().filter((maintenanceOrder)->{
            return maintenanceOrder.getInnerDept() != null && maintenanceOrder.getInnerDept().getId()  != null;
        }).collect(Collectors.groupingBy((maintenanceOrder)->{
            return maintenanceOrder.getInnerDept().getId();
        }));
        if(map.size() > 1) throw new RuntimeException("一个方案只能转一个内协门店");

        //判断需要转的单据是否合格，明细是否能转
        maintenanceOrders.stream().forEach((maintenanceOrder)->{
            if(maintenanceOrder.getInnerDept() == null)
                throw new RuntimeException("勾选商品，必须选内协门店，商品名称：" + maintenanceOrder.getProduct().getName());
//            if(!MaintenanceOrder.WORK_ORDER_COMMON.equals(maintenanceOrder.getBusinessType()))
//                throw new RuntimeException("该组商品不能转内协" );
            if(!maintenanceOrder.getProduct().getProductGroup().checkWorkProduct()) throw new RuntimeException("非工时商品，不能工单转内协");
        });
    }

    /**
     * 转外协(erp操作)
     * @param simpleRequest
     * @return
     */
    public Map toOut(SimpleRequest simpleRequest){
        JSONObject jo = simpleRequest.getJO();
        List<MaintenanceOrder> maintenanceOrders =  maintenanceOrdersTransfer(jo.getJSONArray("maintenanceOrders"));

        String loggerRemark = getLoggerRemark(jo);
        PartyRole person = getPerson(simpleRequest);

        ServicePlan servicePlan = maintenanceOrderOutWorkService.toOutProcess(maintenanceOrders, person);
        toOutErpLogger(servicePlan,person,jo);
        if (person!=null){
            User user =userRepository.findAll(JpaDsl.toCriteriaByEq("person.id",person.getId())).stream().findFirst().orElse(null);
            if (servicePlan.isAutoDispatchProcess())servicePlanceService.addServicePlanLogger(servicePlan,"平台外商品自动派工","",user);
        }
        //如果入口是方案就返回整个方案
        if ("service".equals(jo.getString("entrance")))return MapUtil.mapped(servicePlan);
        return this.invoke("fn.maintenance.findMaintenanceOrderByServicePlan",MapUtil.mapper("SERVICE_PLAN_ID",maintenanceOrders.stream().findFirst().get().getServicePlanItem().queryServicePlanByItem().getId()));
    }
    /**
     * 转外协(App操作)
     * -仅能用于重新转外协,初次转外协有些参数未初始化无法直接使用
     * @param simpleRequest
     * @return
     */
    public Map toOutForApp(SimpleRequest simpleRequest){
        JSONObject jo = simpleRequest.getJO();
        String id = jo.getString("id");
        MaintenanceOrder order = maintenanceOrderRepository.findOne(id);
        String assistType = order.getOutAssistType();
        if (assistType.equals("notOut"))throw new RuntimeException("请先到erp菜单转外协");
        List<MaintenanceOrder> maintenanceOrders = Stream.of(order)
                .peek(maintenanceOrder -> maintenanceOrder.setSelected(true))
                .collect(Collectors.toList());

        PartyRole person = partyRoleRepository.findOne(jo.getString("operator"));

        if (person==null)throw new RuntimeException("当前操作员不存在");

        ServicePlan servicePlan = maintenanceOrderOutWorkService.toOutProcess(maintenanceOrders, person);
        User user =userRepository.findAll(JpaDsl.toCriteriaByEq("person.id",person.getId())).stream().findFirst().orElse(null);
        servicePlanceService.addServicePlanLogger(order.getServicePlanItem().getServicePlan(),"转外协", "",user.getId());
        if (servicePlan.isAutoDispatchProcess())servicePlanceService.addServicePlanLogger(servicePlan,"平台外商品自动派工","",user);

        return MapUtil.mapper("success",true);
    }



    /**
     * 内协工单明细->>方案
     */
    public ServicePlan createServicePlanByInner(List<MaintenanceOrder> maintenanceOrders,Map oldPlanMap){
        if(maintenanceOrders.size() == 0) throw new RuntimeException("工单明细为空，无法生成新方案");
        MaintenanceOrder maintenanceOrder = maintenanceOrders.stream().findFirst().get();

        Dept innerDept = maintenanceOrder.getInnerDept();
        //原方案信息

        ServicePlan newServicePlan = MapUtil.getO(oldPlanMap, ServicePlan.class); //新的方案
        newServicePlan.setId(null);
        newServicePlan.setState("confirm");
        newServicePlan.setPickUpTypeS(null);
        newServicePlan.setPlanType("someAssist");

        //清除来源,防止后续创建工单的时候会锁住工单,生成后会重新回写
        newServicePlan.setSourceBusinessType(null);
        newServicePlan.setSourceBusinessTypeName(null);
        //内协主表需要更改字段
        newServicePlan.setBelongDept(innerDept);
        newServicePlan.setCompany(innerDept.getCompany());
        newServicePlan.setServiceDept(innerDept);
        //接车信息
        newServicePlan.setGetCarInfo(null);
        newServicePlan.setPickCarId(null);
        newServicePlan.setPickCarType(null);
        newServicePlan.setPickCarDate(null);
        newServicePlan.setPickCarName(null);
        servicePlanceService.checkCarInfo(newServicePlan);

        //判断该门店+车是否有唯一的接车拓展信息，有的话，直接用该门店的，没有的话，公用来源门店的
        FnCustomerExpand newFnCustomerExpand = servicePlanceService.findValidServiceFnCustomerExpand(newServicePlan.getBelongDept(),newServicePlan.getFnCustomerExpand().getCarLicense());
        if(newFnCustomerExpand != null)
            newServicePlan.setFnCustomerExpand(newFnCustomerExpand);

        //重取价格（分销协议价）
        JSONArray jgArray = serviceToForeign.getGS51(newServicePlan.getServicePlanItems().stream().map((servicePlanItem)->{
            return MapUtil.mapper(
                    "uniqueIdentify",servicePlanItem.getId(),
                    "SPID",servicePlanItem.getProduct().getId(),
                    "PLID",servicePlanItem.getProduct().getClassify().getId(),
                    "PZID",servicePlanItem.getProduct().getBrand().getQuality() == null ? null : servicePlanItem.getProduct().getBrand().getQuality().getCode(),
                    "GSID",innerDept.getCompany().getId(),
                    "YYMS",servicePlanItem.getServicePlan().getBelongDept().getCompany().getParty().getCorporate().getOperation().getCode(),
                    "NYYMS",innerDept.getCompany().getParty().getCorporate().getOperation().getId(),
                    "KHID",SpringManager.getBean(PartyRoleService.class)
                            .findByPartyAndRole(servicePlanItem.getServicePlan().getSaleDept().getCompany().getParty().getId(), "Customer").getId(),
                    "CGZZID",servicePlanItem.getPlatform().getId(),
                    "JLDW",servicePlanItem.getUom().getName(),
                    "JRS",SpringManager.getBean(AccessProviderRepository.class).findByCompany(innerDept.getCompany().getId()).getId(),
                    "SYGSID",servicePlanItem.getPlatform().getId(),
                    "JCGSID",maintenanceOrder.getBelongDept().getCompany().getId(),
                    "P001",servicePlanItem.getOldInquiryNumber()!=null&&servicePlanItem.getUniqueValue()!=null?servicePlanItem.getPftPriceUnit():null,
                    //"GYSID",servicePlanItem.getSupplier()!=null?servicePlanItem.getSupplier().getId():null,
                    "CLFWDJID",((CarServiceLevel)(SpringManager.getBean(CarServiceLevelService.class).findByCarConfigurationId(newServicePlan.getFnCustomerExpand().getJekunModelCode()))).getId()

            );
        }).collect(Collectors.toList()));

        String COMPANY_ID = newServicePlan.getCompany().getId();
        String OPERATION = newServicePlan.getCompany().getParty().getCorporate().getOperation().getDescription();

        List servicePlanItems = new ArrayList();
        maintenanceOrders.forEach((maintenanceOrder1)->{
//            ServicePlanItem newServicePlanItem = new ServicePlanItem();
//            ReflectUtil.copyAll(maintenanceOrder1.getServicePlanItem(), newServicePlanItem, "");
            ServicePlanItem newServicePlanItem = MapUtil.getO(MapUtil.mapped(maintenanceOrder1.getServicePlanItem()), ServicePlanItem.class);
            boolean flag = true;
            for(int i =0 ;i<jgArray.size();i++){
                JSONObject item = jgArray.getJSONObject(i);
                if(item.getString("uniqueIdentify").equals(newServicePlanItem.getId())){
                    if(item.getDouble("pftPriceUnit") == 0) throw new RuntimeException("["+newServicePlanItem.getProduct().getId()+"]"+newServicePlanItem.getProduct().getName()+",商品未设置分销协议价请联系客服中心对接人！");
                    newServicePlanItem.setPrimaryPriceUnit(item.getDouble("primaryPriceUnit"));
                    newServicePlanItem.setPrimaryPriceUnitShow(item.getDouble("primaryPriceUnit"));
                    newServicePlanItem.setPriceUnit(item.getDouble("priceUnit"));
                    newServicePlanItem.setPftPriceUnit(item.getDouble("pftPriceUnit"));
                    newServicePlanItem.setManagementFeeRate(item.getDouble("managementFeeRate"));
                    newServicePlanItem.setFloorPrice(item.getDouble("floorPrice"));
                    newServicePlanItem.setClerkPriceLimit(item.getDouble("clerkPriceLimit"));
                    newServicePlanItem.setShopOwnerPriceLimit(item.getDouble("shopOwnerPriceLimit"));
                    newServicePlanItem.setCsoPriceLimit(item.getDouble("csoPriceLimit"));
                    newServicePlanItem.setBasePrice(item.getDouble("basePrice"));
                    newServicePlanItem.setDiscountRate(item.getDouble("discountRate"));
                    newServicePlanItem.setPriceCostUnitInTax(item.getDouble("priceCostUnitInTax"));
                    newServicePlanItem.setPriceCostUnitExTax(item.getDouble("priceCostUnitExTax"));
                    newServicePlanItem.setPlatformPriceCosInTax(item.getDouble("platformPriceCosInTax"));
                    newServicePlanItem.setReferTax(item.getDouble("referTax"));
                    flag = false;
                }
            }
            if(flag) throw new RuntimeException("["+newServicePlanItem.getProduct().getId()+"]"+newServicePlanItem.getProduct().getName()+",商品未设置分销协议价请联系客服中心对接人！");
            newServicePlanItem.setEstimatedCommission((Double)(SpringManager.getBean(TCService.class).obtainEstimatedCommission(
                    newServicePlanItem.getProduct().getId(),
                    newServicePlanItem.getProduct().getClassify().getId(),
                    newServicePlanItem.getServeType().getId(),
                    newServicePlanItem.getProduct().getBrand().getId(),
                    newServicePlanItem.getReferTax(),
                    newServicePlanItem.getPftPriceUnit(),
                    newServicePlanItem.getFloorPrice(),
                    newServicePlanItem.getPriceUnit(),
                    COMPANY_ID,OPERATION
            )));
            newServicePlanItem.setId(null);
            newServicePlanItem.setServicePlan(null);
            newServicePlanItem.setHigherLevelCode(null);
            newServicePlanItem.setServicePlan(newServicePlan);
            //内协重取仓库
            if(!newServicePlan.getBelongDept().getCompany().getId().equals(newServicePlan.getSaleDept().getCompany().getId())){
                newServicePlanItem.setLocation(
                        SpringManager.getBean(LocationService.class).findLocationByDept(newServicePlan.getBelongDept(),newServicePlanItem.isProductRule())
                );
            }

            newServicePlanItem.setParentServicePlanItem(maintenanceOrder1.getServicePlanItem());
            newServicePlanItem.setMainSaler(null);
            newServicePlanItem.setSupSaler(null);
//            try {
//                Location location = SpringManager.getBean(LocationRepository.class).findAll(JpaDsl.toCriteriaByEq("dept.id", newServicePlan.getBelongDept().getId(), "usage.id", "1")).stream().findFirst().get();
//                newServicePlanItem.setLocation(location);
//            } catch (Exception e) {
//                throw new RuntimeException("innerMistake:重取仓库有误");
//            }
            servicePlanItems.add(newServicePlanItem);
        });
        newServicePlan.setServicePlanItems(servicePlanItems);
        return servicePlanceService.updateServicePlanForMoney(newServicePlan);
    }

    public void setPlanSource(ServicePlan baseServicePlan, ServicePlan deptServicePlan) {
        if ("appOrder".equals(deptServicePlan.getSourceBusinessType())){
            baseServicePlan.setSourceBusinessType(deptServicePlan.getSourceBusinessType());
            baseServicePlan.setSourceBusinessTypeName(deptServicePlan.getSourceBusinessTypeName());
            baseServicePlan.setSourceFrom(deptServicePlan.getSourceFrom());
        }else if ("LossQuotation".equals(deptServicePlan.getSourceBusinessType())){
            baseServicePlan.setSourceBusinessType(deptServicePlan.getSourceBusinessType());
            baseServicePlan.setSourceBusinessTypeName(deptServicePlan.getSourceBusinessTypeName());
            baseServicePlan.setSourceFrom(deptServicePlan.getSourceFrom());
        }else {
            baseServicePlan.setSourceBusinessType(deptServicePlan.getBusinessType());
            baseServicePlan.setSourceBusinessTypeName(deptServicePlan.getBusinessTypeName());
            baseServicePlan.setSourceFrom(deptServicePlan.getId());
        }
    }

//    public ServicePlan createServicePlanByInner(List<MaintenanceOrder> maintenanceOrders){
//        if(maintenanceOrders.size() == 0) throw new RuntimeException("工单明细为空，无法生成新方案");
//        MaintenanceOrder maintenanceOrder = maintenanceOrders.stream().findFirst().get();
//        Dept innerDept = maintenanceOrder.getInnerDept();
//        //原方案信息
//        ServicePlan oldServicePlan
//                = maintenanceOrders.stream().findFirst().get().getServicePlanItem().queryServicePlanByItem();
//
//        ServicePlan newServicePlan = new ServicePlan();
//        ReflectUtil.copyAll(oldServicePlan, newServicePlan, "id");
//
//
//        JSONArray jgArray = serviceToForeign.getXS51(
//                newServicePlan.getServicePlanItems().stream().filter((servicePlanItem)->{
//                    return servicePlanItem.getOldInquiryNumber() == null;
//                }).map((servicePlanItem)->{
//                    return MapUtil.mapper(
//                            "uniqueIdentify",servicePlanItem.getId(),
//                            "MDID",newServicePlan.getBelongDept().getId(),
//                            "PLID",servicePlanItem.getProduct().getClassify().getId(),
//                            "SPID",servicePlanItem.getProduct().getId(),
//                            "HZLXID",newServicePlan.getCooperationType() == null ? null : newServicePlan.getCooperationType().getId(),
//                            "PPID",servicePlanItem.getProduct().getBrand().getId(),   //品牌找品质
//                            "XSZZID",newServicePlan.getBelongDept().getCompany().getId(),
//                            "GSID",newServicePlan.getBelongDept().getCompany().getId(),
////                        "CLFWDJID",,
//                            "MDLXID",newServicePlan.getBelongDept().getDeptType().getId(),
////                        "FNVIPJBID",,
////                        "FNVIPSFID",fnCustomer.getString("id"),
//                            "CGZZID",servicePlanItem.getPlatform().getId(),
//                            "JLDW",servicePlanItem.getUom().getName(),
//                            "SYGSID",servicePlanItem.getPlatform().getId(),
//                            "XYGSID",newServicePlan.getBelongDept().getCompany().getId()
//                    );
//                }).collect(Collectors.toList())
//        );
//
//
//        jgArray.addAll(serviceToForeign.getXJ51(newServicePlan.getServicePlanItems().stream().filter((servicePlanItem)->{
//            return servicePlanItem.getOldInquiryNumber() != null;
//        }).map((servicePlanItem)->{
//            return MapUtil.mapper(
//                    "uniqueIdentify",servicePlanItem.getId(),
//                    "MDID",newServicePlan.getBelongDept().getId(),
//                    "PLID",servicePlanItem.getProduct().getClassify().getId(),
//                    "SPID",servicePlanItem.getProduct().getId(),
//                    "FNVIPJBID","",
//                    "FNVIPSFID","",
//                    "JLDW",servicePlanItem.getUom().getName(),
//                    "XYGSID",newServicePlan.getBelongDept().getCompany().getId(),
//                    "XSDJ",servicePlanItem.getInquiryPriceUnit(),
//                    "XSXJ",servicePlanItem.getInquiryPriceLimit()
//            );
//        }).collect(Collectors.toList())));
//
//
//        //内协主表需要更改字段
//        newServicePlan.setBelongDept(innerDept);
//        newServicePlan.setCompany(innerDept.getCompany());
//        newServicePlan.setServiceDept(innerDept);
//
//        Set servicePlanItems = new HashSet();
//        maintenanceOrders.forEach((maintenanceOrder1)->{
//            ServicePlanItem newServicePlanItem = new ServicePlanItem();
//            ReflectUtil.copyAll(maintenanceOrder1.getServicePlanItem(), newServicePlanItem, "");
//
//            for(int i =0 ;i<jgArray.size();i++){
//                JSONObject item = jgArray.getJSONObject(i);
//                if(item.getString("uniqueIdentify").equals(newServicePlanItem.getId())){
//                    newServicePlanItem.setPrimaryPriceUnit(item.getDouble("primaryPriceUnit"));
//                    newServicePlanItem.setPriceUnit(item.getDouble("priceUnit"));
//                    newServicePlanItem.setPftPriceUnit(item.getDouble("pftPriceUnit"));
//                    newServicePlanItem.setManagementFeeRate(item.getDouble("managementFeeRate"));
//                    newServicePlanItem.setFloorPrice(item.getDouble("floorPrice"));
//                    newServicePlanItem.setClerkPriceLimit(item.getDouble("clerkPriceLimit"));
//                    newServicePlanItem.setShopOwnerPriceLimit(item.getDouble("shopOwnerPriceLimit"));
//                    newServicePlanItem.setCsoPriceLimit(item.getDouble("csoPriceLimit"));
//                    newServicePlanItem.setBasePrice(item.getDouble("basePrice"));
//                    newServicePlanItem.setDiscountRate(item.getDouble("discountRate"));
//                }
//            }
//            newServicePlanItem.setPriceCostUnitInTax(maintenanceOrder1.getServicePlanItem().getPftPriceUnit());
//            newServicePlanItem.setPriceCostUnitExTax(maintenanceOrder1.getServicePlanItem().getPftPriceUnit());
//            newServicePlanItem.setPlatformPriceCosInTax(maintenanceOrder1.getServicePlanItem().getPftPriceUnit());
//            newServicePlanItem.setId(null);
//            newServicePlanItem.setServicePlan(newServicePlan);
//            newServicePlanItem.setHigherLevelCode(null);
//            servicePlanItems.add(newServicePlanItem);
//        });
//        //  newServicePlan.setServicePlanItems(servicePlanItems);
////        newServicePlan = servicePlanceService.updateOnly(newServicePlan);
////        return this.invoke("fn.service.create",MapUtil.mapped(newServicePlan));
//        SpringManager.getBean(SequenceService.class).setId(newServicePlan);
//        return servicePlanceService.updateOnly(newServicePlan);
//    }

    private ServicePlan toInnerNewToNew(List<MaintenanceOrder> maintenanceOrders,PartyRole role){
        ServicePlan servicePlan = maintenanceOrders.stream().findFirst().get().getServicePlanItem().queryServicePlanByItem();
        if (servicePlan.getTerminationDate()!=null)return servicePlan;
        Map oldPlanMap = MapUtil.mapped(servicePlan);
        //根据工单明细
        ServicePlan newServicePlan = createServicePlanByInner(maintenanceOrders,oldPlanMap); //生成对应方案
        newServicePlan.setOperator1(role);
        servicePlanceService.innerCreateMaintenanceOrder(newServicePlan); //生成对应工单

        //处理当前工单,方案数据
        setPlanSource(newServicePlan,servicePlan);
        BusinessAttributeValue businessAttributeValue = businessAttributeValueRepository.findOne("ServicePlanItem.assistType.inner");
        maintenanceOrders.forEach((maintenanceOrder)->{
            maintenanceOrder.setState(MaintenanceOrder.CONST_TABLE_STATE_INNER);
            maintenanceOrder.setToInnerDate(new Date());
            maintenanceOrder.setToInnerUid(role);
            maintenanceOrder.setLockState(false);

            servicePlan.getServicePlanItems().forEach((servicePlanItem)->{
                if(servicePlanItem.getId().equals(maintenanceOrder.getServicePlanItem().getId())){
                    servicePlanItem.setAssistType(businessAttributeValue);
                }
            });
        });

        String COMPANY_ID = servicePlan.getCompany().getId();
        String OPERATION = servicePlan.getCompany().getParty().getCorporate().getOperation().getDescription();
        newServicePlan.getServicePlanItems().stream().forEach(servicePlanItem -> {
            servicePlan.getServicePlanItems().stream().forEach(servicePlanItem1 -> {
                if(servicePlanItem.getParentServicePlanItem().getId().equals(servicePlanItem1.getId())){
                    servicePlanceService.innerPlanGetPriceCostUnit(servicePlanItem1,servicePlanItem);
                    servicePlanItem1.setPlatformPriceCosInTax(servicePlanItem.getPftPriceUnit());
                    servicePlanItem1.setReferTax(servicePlanItem.getPftPriceUnit());
                    servicePlanItem1.setInnerReferTax(servicePlanItem.getPftPriceUnit());

                    servicePlanItem1.setEstimatedCommission((Double)(SpringManager.getBean(TCService.class).obtainEstimatedCommission(
                            servicePlanItem1.getProduct().getId(),
                            servicePlanItem1.getProduct().getClassify().getId(),
                            servicePlanItem1.getServeType().getId(),
                            servicePlanItem1.getProduct().getBrand().getId(),
                            servicePlanItem1.getReferTax(),
                            servicePlanItem1.getPftPriceUnit(),
                            servicePlanItem1.getFloorPrice(),
                            servicePlanItem1.getPriceUnit(),
                            COMPANY_ID,OPERATION
                    )));
                }
            });
        });
        updateMaintenanceOrders(maintenanceOrders);
        servicePlanceService.toInnerItemWrite(newServicePlan);
        servicePlanceService.confirmToApp(newServicePlan);
        servicePlanceService.addServicePlanLogger(newServicePlan,"内协生成方案",newServicePlan.getSaleDept().getName()+"内协至"+newServicePlan.getServiceDept().getName());
        return servicePlanceService.updateOnly(servicePlan);
    }

    /**
     * 生成老框架的内协流程
     *
     * @param innerDept
     */
    private void toInnerNewToOld(List<MaintenanceOrder> maintenanceOrders, Dept innerDept, PartyRole role) {
        //分销协议价格，绑定客户
        PartyRole customer = SpringManager.getBean(PartyRoleService.class)
                .findByPartyAndRole(innerDept.getCompany().getParty().getId(), "Customer");
        if (customer == null) throw new RuntimeException("当前公司未绑定客户");
        //重取价格（分销协议价）
        JSONArray jgArray = serviceToForeign.getGS51(maintenanceOrders.stream().map((maintenanceOrder)->{
            return MapUtil.mapper(
                    "uniqueIdentify",maintenanceOrder.getId(),
                    "SPID",maintenanceOrder.getProduct().getId(),
                    "PLID",maintenanceOrder.getProduct().getClassify().getId(),
                    "PZID",maintenanceOrder.getProduct().getBrand().getQuality() == null ? null : maintenanceOrder.getProduct().getBrand().getQuality().getCode(),
                    "GSID",innerDept.getCompany().getId(),
                    "YYMS",maintenanceOrder.getBelongDept().getCompany().getParty().getCorporate().getOperation().getCode(),
                    "KHID",SpringManager.getBean(PartyRoleService.class)
                            .findByPartyAndRole(maintenanceOrder.getBelongDept().getCompany().getParty().getId(), "Customer").getId(),
                    "CGZZID",maintenanceOrder.getPlatform().getId(),
                    "JLDW",maintenanceOrder.getUom().getName(),
                    "SYGSID",innerDept.getCompany().getId(),
                    "JRS",maintenanceOrder.getFnCustomerExpand().getVendorCode(),
                    "JCGSID",maintenanceOrder.getBelongDept().getCompany().getId(),
                    "CLFWDJID",((CarServiceLevel)(SpringManager.getBean(CarServiceLevelService.class).findByCarConfigurationId(maintenanceOrder.getFnCustomerExpand().getJekunModelCode()))).getId()

            );
        }).collect(Collectors.toList()));

        //先进行车辆等数据同步  //同步旧系统接车
        JSONObject reJson =
                this.invoke("fn.deliveryOrder.acrossSystemCreateVipDetail", MapUtil.mapper(
                        "customerExpandId", maintenanceOrders.stream().findFirst().get().getFnCustomerExpand().getId(),
                        "deliveryCompanyId", maintenanceOrders.stream().findFirst().get().getBelongDept().getCompany().getId(),
                        "receiptCompanyId", innerDept.getCompany().getId()
                ));

        String sVIPID;
        String sCLNM;

        try {
            sVIPID = JSONObject.parseObject(reJson.getString("obj")).getString("VIPID");
            sCLNM = JSONObject.parseObject(reJson.getString("obj")).getString("CLNM");
        } catch (Exception e) {
            throw new RuntimeException("转内协失败，同步车辆信息有误");
        }


        Map resultMap = new HashMap();
        resultMap.put("SER_FWD", MapUtil.mapper(
                "GSID", innerDept.getCompany().getId(),
                "MDID", innerDept.getId(),
                "MDMC", innerDept.getName(),
                "FWMDID", innerDept.getId(),
                "FWMDMC", innerDept.getName(),
                "NXMDID", maintenanceOrders.stream().findFirst().get().getBelongDept().getOrigin(),
                "QDID", maintenanceOrders.stream().findFirst().get().getServicePlanItem().getServicePlan().getChannel() == null ? null : maintenanceOrders.stream().findFirst().get().getServicePlanItem().getServicePlan().getChannel().getId(),
                "VIPID", sVIPID,
                "CLNM", sCLNM,
                "CZYID", role.getId(),
                "YBWDS", "123456"

        ));
        resultMap.put("SER_FWDFA", MapUtil.mapper(
                "XSJE", maintenanceOrders.stream().mapToDouble((workOrderItem) -> {
                    return workOrderItem.getServicePlanItem().getSalesAmount();
                }).sum(),
                "XSJE1", maintenanceOrders.stream().mapToDouble((workOrderItem) -> {
                    return workOrderItem.getServicePlanItem().getSalesAmount();
                }).sum(),
                "FAHGBJ", "1",
//                "YJJCSJ", maintenanceOrders.stream().findFirst().get().getServicePlanItem().getServicePlan().getEstimatedDeliveryDate(),
                "FAQRBJ", "1",
                "QRFS", "1",
                "BZ", maintenanceOrders.stream().findFirst().get().getServicePlanItem().getServicePlan().getDeptRemark(),
                "CZY", role.getName(),
                "GSID", innerDept.getCompany().getId(),
                "AQTS", maintenanceOrders.stream().findFirst().get().getServicePlanItem().getServicePlan().getSafetyTips(),
//                "YJJCRQ_SJ", maintenanceOrders.stream().findFirst().get().getServicePlanItem().getServicePlan().getEstimatedDeliveryDate(),
                "FADJZT", "0",
                "XKJFAH", maintenanceOrders.stream().findFirst().get().getServicePlanItem().getServicePlan().getId(),
                "MDID", innerDept.getId(),
                "SER_FASP1", maintenanceOrders.stream().map((maintenanceOrder) -> {
                    ServicePlanItem servicePlanItem = maintenanceOrder.getServicePlanItem();
                    JSONArray ppArray = jgArray.stream().filter((item) -> {
                        JSONObject item1 = new JSONObject((Map) item);
                        return maintenanceOrder.getId().equals(item1.getString("uniqueIdentify"));
                    }).collect(Collectors.toCollection(JSONArray::new));
                    if (ppArray.size() != 1) throw new RuntimeException("商品获取价格失败");
                    JSONObject ppJson = new JSONObject((Map) ppArray.stream().findFirst().get());
                    if (ppJson.getDouble("pftPriceUnit") == 0)
                        throw new RuntimeException("内协门店没有设置对本店的分销协议价，请先联系客服设置，商品名称：" + maintenanceOrder.getProduct().getName());
                    return MapUtil.mapper(
                            "SPID", servicePlanItem.getProduct().getId(),
                            "SPMC", servicePlanItem.getProduct().getName(),
                            "PLID", servicePlanItem.getProduct().getClassify().getId(),
                            "PLMC", servicePlanItem.getProduct().getClassify().getName(),
                            "PPID", servicePlanItem.getProduct().getBrand().getId(),
                            "PPMC", servicePlanItem.getProduct().getBrand().getName(),
                            "SPZID", servicePlanItem.getProduct().getProductGroup().getId(),
                            "SPZMC", servicePlanItem.getProduct().getProductGroup().getName(),
                            "SPXH", servicePlanItem.getProduct().getModel(),
                            "GG", servicePlanItem.getProduct().getSpecifications(),
                            "JLDW", servicePlanItem.getUom().getName(),
                            "HSBL", servicePlanItem.getUom().getFactor(),
                            "XSJS", servicePlanItem.getSaleQty(),
                            "XSSL", servicePlanItem.getSalesVolume(),
                            "ZDXJ", ppJson.getDouble("floorPrice"),
                            "YXSDJ", ppJson.getDouble("primaryPriceUnit"),
                            "XSJZJ", ppJson.getDouble("basePrice"),
                            "ZKL", ppJson.getDouble("discountRate"),
                            "YHDJ", ppJson.getDouble("pftPriceUnit"),
                            "XSDJ", ppJson.getDouble("priceUnit"),
//                                    "XSJE",ppJson.getDouble("salesAmount"),
                            "CBDJ", ppJson.getDouble("priceCostUnitExTax"),
                            "HSCBDJ", ppJson.getDouble("priceCostUnitInTax"),
                            "YCBDJ", ppJson.getDouble("platformPriceCosInTax"),
                            "DZXJ", ppJson.getDouble("shopOwnerPriceLimit"),
                            "DYXJ", ppJson.getDouble("clerkPriceLimit"),
                            "XSZJXJ", ppJson.getDouble("csoPriceLimit"),
                            "SSBL", servicePlanItem.getProduct().getTax().obtainPercentTypeTax(),
                            "CKKQID", servicePlanItem.getLocation().getId(),
                            "CKKQMC", servicePlanItem.getLocation().getName(),
                            "GSID", servicePlanItem.getLocation().getCompany().getId(),
                            "GSMC", servicePlanItem.getLocation().getCompany().getName(),
                            "DABJ", servicePlanItem.isProductRule() ? 1 : "10".equals(servicePlanItem.getProduct().getProductGroup()) ? 0 : 2,
                            "KSFWBJ", servicePlanItem.getProduct().isFreeServiceValid() ? 1 : 0,
                            "FWLXID", servicePlanItem.getServeType().getId(),
                            "FWLXMC", servicePlanItem.getServeType().getName(),
//                            "ZXSYID", servicePlanItem.getMainSaler() != null ? servicePlanItem.getMainSaler().getId() : null,
//                            "ZXSYMC", servicePlanItem.getMainSaler() != null ? servicePlanItem.getMainSaler().getName() : null,
//                            "FXSYID", servicePlanItem.getSupSaler() != null ? servicePlanItem.getSupSaler().getId() : null,
//                            "FXSYMC", servicePlanItem.getSupSaler() != null ? servicePlanItem.getSupSaler().getName() : null,
                            "TYZXBJ", servicePlanItem.isServiceState() ? 1 : 0,
                            "SFWXBJ", "0",
                            "SGMDID", innerDept.getId(),
                            "SGMDMC", innerDept.getName(),
                            "WXPGBJ", 0,
                            "PJMCID", servicePlanItem.getCategory().getId(),
                            "PJMC", servicePlanItem.getCategory().getName(),
                            "ZBQ", servicePlanItem.getQualityWarranty(),
                            "ZBLC", servicePlanItem.getQualityMileage(),
                            "GLFY", servicePlanItem.getManagementCost(),
                            "PTID", servicePlanItem.getPlatform().getId(),
                            "FNMDXSJE",servicePlanItem.getSalesAmount()
                    );
                }).collect(Collectors.toCollection(HashSet::new))
        ));
        resultMap.put("SER_FWGD", MapUtil.mapper(
                "VIPID", sVIPID,
                "CLNM", sCLNM,
                "MDID", innerDept.getId(),
                "MDMC", innerDept.getName(),
                "PGMDID", innerDept.getId(),
                "PGMDMC", innerDept.getName(),
                "SGMDID", innerDept.getId(),
                "SGMDMC", innerDept.getName(),
                "XSJE", maintenanceOrders.stream().mapToDouble((maintenanceOrder) -> {
                    return maintenanceOrder.getServicePlanItem().getSalesAmount();
                }).sum(),
                "DJZT", 0,
                "GSID", innerDept.getCompany().getId(),
                "SER_FWGDMX", maintenanceOrders.stream().map((maintenanceOrder) -> {
                    JSONArray ppArray = jgArray.stream().filter((item) -> {
                        JSONObject item1 = new JSONObject((Map) item);
                        return maintenanceOrder.getId().equals(item1.getString("uniqueIdentify"));
                    }).collect(Collectors.toCollection(JSONArray::new));
                    if (ppArray.size() != 1) throw new RuntimeException("商品获取价格失败");
                    JSONObject ppJson = new JSONObject((Map) ppArray.stream().findFirst().get());
                    return MapUtil.mapper(
                            "SPID", maintenanceOrder.getProduct().getId(),
                            "SPMC", maintenanceOrder.getProduct().getName(),
                            "PLID", maintenanceOrder.getProduct().getClassify().getId(),
                            "PLMC", maintenanceOrder.getProduct().getClassify().getName(),
                            "PPID", maintenanceOrder.getProduct().getBrand().getId(),
                            "PPMC", maintenanceOrder.getProduct().getBrand().getName(),
                            "SPZID", maintenanceOrder.getProduct().getProductGroup().getId(),
                            "SPZMC", maintenanceOrder.getProduct().getProductGroup().getName(),
                            "SPXH", maintenanceOrder.getProduct().getModel(),
                            "GG", maintenanceOrder.getProduct().getSpecifications(),
                            "JLDW", maintenanceOrder.getUom().getName(),
                            "HSBL", maintenanceOrder.getUom().getFactor(),
                            "XSJS", maintenanceOrder.getServicePlanItem().getSaleQty(),
                            "XSSL", maintenanceOrder.getServicePlanItem().getSalesVolume(),
                            "YHDJ", ppJson.getDouble("pftPriceUnit"),
                            "XSDJ", ppJson.getDouble("priceUnit"),
                            "XSJE", ppJson.getDouble("pftPriceUnit") * maintenanceOrder.getSaleQty(),
                            "XSJZJ", maintenanceOrder.getServicePlanItem().getBasePrice(),

                            "FWLXID", maintenanceOrder.getServeType().getId(),
                            "FWLXMC", maintenanceOrder.getServeType().getName(),
                            "CKKQID", maintenanceOrder.getServicePlanItem().getLocation().getId(),
                            "CKKQMC", maintenanceOrder.getServicePlanItem().getLocation().getName(),

                            "GLFL", maintenanceOrder.getServicePlanItem().getManagementFeeRate(),
                            "GLFY", maintenanceOrder.getServicePlanItem().getManagementCost(),
                            "YXSDJ", maintenanceOrder.getServicePlanItem().getPrimaryPriceUnit(),
                            "CBDJ", maintenanceOrder.getServicePlanItem().getPriceCostUnitExTax(),
                            "HSCBDJ", maintenanceOrder.getServicePlanItem().getPriceCostUnitInTax(),
                            "PTID", maintenanceOrder.getServicePlanItem().getPlatform().getId()
                    );
                }).collect(Collectors.toCollection(HashSet::new))
        ));

        //更改原工单成本
//        rewritePriceFromToInner(
//                !workOrder.getBelongDept().getCompany().getId().equals(innerDept.getCompany().getId())
//                , workOrder
//                , jgArray);

        //保存工单
        List<MaintenanceOrder> maintenanceOrderList = updateMaintenanceOrders(maintenanceOrders);

        List<String> idList = maintenanceOrderList.stream().map(maintenanceOrder -> maintenanceOrder.getId()).collect(Collectors.toList());
        //异步生成老框架
        maintenanceToInner(resultMap,jgArray,idList,role.getId(),maintenanceOrders.stream().findFirst().get().getServicePlanItem().queryServicePlanByItem().getId());


    }


    private String tranferWorkByArray(JSONArray worker1) {
        if(worker1 == null || worker1.size() == 0) return null;
        List workList = worker1.stream().map(item ->{
            PartyRole role = partyRoleRepository.findOne(((JSONObject)item).getString("id"));
            if(role == null) throw new RuntimeException("施工人实体不存在，编码：" + ((JSONObject)item).getString("id"));
            return MapUtil.mapper("id",role.getId(),"name",role.getName());
        }).collect(Collectors.toList());
        return JSON.toJSONString(workList);
    }

    /**
     * 批量更新
     * @param maintenanceOrders
     * @return
     */
    public List<MaintenanceOrder> updateMaintenanceOrders(List<MaintenanceOrder> maintenanceOrders){
        maintenanceOrders.forEach((maintenanceOrder)->{
            String pId = "";
            if(maintenanceOrder.getContract() != null){
                if("Contract.contractType.supplier".equals(maintenanceOrder.getContract().getContractType().getId())){ //1001
                    pId= "1001";
                }else{ //1007
                    pId= "1007";
                }
                maintenanceOrder.setPlatform(SpringManager.getBean(PartyRoleService.class).findOne(pId,"Company"));
            }
            maintenanceOrder =  create(maintenanceOrder);
        });
        return maintenanceOrders;
    }


    /**
     * 根据方案号，解锁所有锁住工单
     * @param simpleRequest simpleRequest
     * @return Map
     */
    public Map unLockMaintenanceOrder(SimpleRequest simpleRequest){
        ServicePlan servicePlan = simpleRequest.getO(ServicePlan.class); //该转换对象 只会存在一个编码
        // 需要先判断是否存在本地接车单(用户接车或内协接车单)
        servicePlan = servicePlanRepository.findOne(servicePlan.getId());
        String carLicense = servicePlan.getFnCustomerExpand().getCarLicense();
        List<PickUpCar> pickUpCar = SpringManager.getBean(PickUpCarRepository.class).findAll(
                JpaDsl.toCriteriaByEq("dept.id",servicePlan.getServiceDept().getId(),
                        "licenseNumber",carLicense,"state","approve")
        );
        if (pickUpCar.size() ==0){
            List<InnerPickDeliveryUpCar> innerPickUpCars =  SpringManager.getBean(InnerPickDeliveryUpCarRepository.class).findAll(
                    JpaDsl.toCriteriaByEq("fnCustomerExpand.carLicense", carLicense, "otherSideDept.id", servicePlan.getServiceDept().getId(), "state", "get")
            );
            if (innerPickUpCars.size() == 0) throw new RuntimeException("车牌:"+carLicense+"不存在本店接车单，请先用户接车或内协接车再转工单!!!");
        }
//        List<MaintenanceOrder> maintenanceOrders = servicePlan.getServicePlanItems();
        List<MaintenanceOrder> maintenanceOrders = maintenanceOrderRepository.findAll(JpaDsl.toCriteriaByEq("servicePlanItem.servicePlan.id",servicePlan.getId()));
        maintenanceOrders.forEach(maintenanceOrder -> {
            maintenanceOrder.setLockState(false);
        });
        updateMaintenanceOrders(maintenanceOrders);
        servicePlanceService.updateOnly(servicePlan);
        return MapUtil.mapper("success",true);

    }

    public void calcutelateTimeA(SimpleRequest req){
        JSONObject jo = req.getJO();
        ConstructionRecord constructionRecord = SpringManager.getBean(ConstructRecordRepository.class).findOne(jo.getString("id"));
        calcutelateTime(constructionRecord);
    }

    @OutboxSubscriber(name = "施工记录回写工单")
    public void calcutelateTime(ConstructionRecord constructionRecord) {
        String state = constructionRecord.getOperateType();
        MaintenanceOrder maintenanceOrder = maintenanceOrderRepository.findOne(constructionRecord.getMaintenanceOrder().getId());
        maintenanceOrder.setPauseedTime(0);
        maintenanceOrder.setWorkedTime(0);
        switch (state){
            case "start":
                maintenanceOrder.setWorkStartTime(constructionRecord.getCreateDate());
                maintenanceOrder.setPoint("start");
                maintenanceOrder.setPointStartTime(constructionRecord.getCreateDate());
               break;
            case "renew":
                maintenanceOrder.setPoint("start");
                maintenanceOrder.setPointStartTime(constructionRecord.getCreateDate());
                break;
            case "pause":
                maintenanceOrder.setPoint("pause");
                maintenanceOrder.setPointStartTime(constructionRecord.getCreateDate());
                break;
            case "finish":
                maintenanceOrder.setPoint("finish");
                maintenanceOrder.setPointStartTime(constructionRecord.getCreateDate());
                maintenanceOrder.setFinishDate(constructionRecord.getCreateDate());
                break;
            case "end":
                maintenanceOrder.setPoint("finish");
                maintenanceOrder.setPointStartTime(constructionRecord.getCreateDate());

                //如果该工单属于施工中，突然暂停，还需要加上一段时间（可能是暂停时间，也可能是施工时长）
                if("pause".equals(constructionRecord.getLastConstructionRecord().getOperateType())){
                    maintenanceOrder.setPauseedTime(
                            Math.floor((constructionRecord.getCreateDate().getTime() - constructionRecord.getLastConstructionRecord().getCreateDate().getTime())/60/1000)
                    );
                }else{
                    maintenanceOrder.setWorkedTime(
                            Math.floor((constructionRecord.getCreateDate().getTime() - constructionRecord.getLastConstructionRecord().getCreateDate().getTime())/60/1000)
                    );
                }
                break;
            default:
        }
        JSONObject json = new JSONObject();
        json.put("maintenanceOrderId",maintenanceOrder.getId());
        maintenanceOrder.setPauseedTime(maintenanceOrder.getPauseedTime() + servicePlanDao.queryMainteinorderPauseTime(json));
        maintenanceOrder.setWorkedTime(maintenanceOrder.getWorkedTime() + servicePlanDao.queryMainteinorderWorkTime(json));

        //存在工单会把完成状态改成新增状态，此处做一个判断。如果发生，则把状态进行改回。
        if(maintenanceOrder.getFinishDate() != null && LogicalUtil.notIn(maintenanceOrder.getState(),MaintenanceOrder.CONST_TABLE_STATE_FINISH,MaintenanceOrder.CONST_TABLE_STATE_TERMINATION))
            maintenanceOrder.setState(MaintenanceOrder.CONST_TABLE_STATE_FINISH);

        maintenanceOrderRepository.saveAndFlush(maintenanceOrder);
    }

    public MaintenanceOrder calcutelateTimeNow(ConstructionRecord constructionRecord,MaintenanceOrder maintenanceOrder){
        String state = constructionRecord.getOperateType();
        maintenanceOrder.setPauseedTime(0);
        maintenanceOrder.setWorkedTime(0);
        switch (state){
            case "start":
                maintenanceOrder.setWorkStartTime(constructionRecord.getCreateDate());
                maintenanceOrder.setPoint("start");
                maintenanceOrder.setPointStartTime(constructionRecord.getCreateDate());
                break;
            case "renew":
                maintenanceOrder.setPoint("start");
                maintenanceOrder.setPointStartTime(constructionRecord.getCreateDate());
                break;
            case "pause":
                maintenanceOrder.setPoint("pause");
                maintenanceOrder.setPointStartTime(constructionRecord.getCreateDate());
                break;
            case "finish":
                maintenanceOrder.setPoint("finish");
                maintenanceOrder.setPointStartTime(constructionRecord.getCreateDate());
                maintenanceOrder.setFinishDate(constructionRecord.getCreateDate());
                break;
            case "end":
                maintenanceOrder.setPoint("finish");
                maintenanceOrder.setPointStartTime(constructionRecord.getCreateDate());

                //如果该工单属于施工中，突然暂停，还需要加上一段时间（可能是暂停时间，也可能是施工时长）
                if("pause".equals(constructionRecord.getLastConstructionRecord().getOperateType())){
                    maintenanceOrder.setPauseedTime(
                            Math.floor((constructionRecord.getCreateDate().getTime() - constructionRecord.getLastConstructionRecord().getCreateDate().getTime())/60/1000)
                    );
                }else{
                    maintenanceOrder.setWorkedTime(
                            Math.floor((constructionRecord.getCreateDate().getTime() - constructionRecord.getLastConstructionRecord().getCreateDate().getTime())/60/1000)
                    );
                }
                break;
            default:
        }
        JSONObject json = new JSONObject();
        json.put("maintenanceOrderId",maintenanceOrder.getId());
        maintenanceOrder.setPauseedTime(maintenanceOrder.getPauseedTime() + servicePlanDao.queryMainteinorderPauseTime(json));
        maintenanceOrder.setWorkedTime(maintenanceOrder.getWorkedTime() + servicePlanDao.queryMainteinorderWorkTime(json));
        return maintenanceOrder;
    }


    /**
     *  传入字段： operate
     *  id
     * @param simpleRequest
     */
    public void dealRenewWorkForHistory(SimpleRequest simpleRequest){
        JSONObject jo= simpleRequest.getJO();
        Date startDate = jo.getDate("startDate");
        Date endDate = jo.getDate("endDate");

        Date tempStartDate = startDate;
        Date tempEndDate = startDate;


        while(true){
            tempEndDate = DateUtil.add(tempEndDate, Calendar.DATE, 1);
            if(tempEndDate.getTime() > endDate.getTime()){ //超出制定范围，直接返回
                break;
            }
            List<MaintenanceOrder> list = maintenanceOrderRepository.findMaintenanceWorkderForHistory(tempStartDate,tempEndDate);
            if(list.size() != 0){
                EventUtil.sendAynEvent(this,"event:maintenorder.history.worker",list);
            }
        }
    }


    @Listener(topic = "event:maintenorder.history.worker")
    public void dealHistoryMainterorder(SimpleRequest req){
        List<MaintenanceOrder> list = (ArrayList)req.getData();
        list.forEach(maintenanceOrder -> {
            maintenanceOrder.setWorker1Show(maintenanceOrder.changeWorkerToWorkerShow(maintenanceOrder.getWorker1()));
            maintenanceOrder.setWorker2Show(maintenanceOrder.changeWorkerToWorkerShow(maintenanceOrder.getWorker2()));
            maintenanceOrder.setWorker3Show(maintenanceOrder.changeWorkerToWorkerShow(maintenanceOrder.getWorker3()));
            maintenanceOrder.setWorker4Show(maintenanceOrder.changeWorkerToWorkerShow(maintenanceOrder.getWorker4()));
            maintenanceOrderRepository.save(maintenanceOrder);
        });
    }

    public void dealMaintenanceError(){
        Sort sort = new Sort(Sort.Direction.ASC, "id");
        int page  = 0;
        while(true){
            List<MaintenanceOrder> list = maintenanceOrderRepository.findAll(JpaDsl.toCriteria("pauseedTime","NE",0),PageRequest.of(page, 1000,sort)).getContent();




            list.forEach(maintenanceOrder -> {
                MQUtil.publish("maintenanceOrder.report.dealMaintenanceErrorConsumer", "工单生成报表", MapUtil.mapper("id",maintenanceOrder.getId()));
            });
            if (list.size() < 1000) {
                break;
            }
            page ++;
        }
    }

    @Consumer(topic = "maintenanceOrder.report.dealMaintenanceErrorConsumer")
    public void dealMaintenanceErrorConsumer(SimpleRequest re){
//        maintenanceOrderReportRepository.saveAndFlush(constructMaintenanceOrderReport(constructRecordRepository.findOne(re.getJO().getString("id"))));
    }

    /**
     * 非钣喷端修改施工人   施工人1
     * @param re
     * @return
     */
    public Map updateWorker(SimpleRequest re){
        JSONObject jo = re.getJO();
        String id = jo.getString("id");
        JSONArray array = JSONArray.parseArray(jo.getString("workList"));
        List<JSONObject> workList = new ArrayList<>();
        array.forEach(item -> {
            JSONObject json = (JSONObject)item;
            PartyRole role = partyRoleRepository.findOne(json.getString("id"));
            if(role == null) throw new RuntimeException("施工人在系统不存在，系统传参错误，编码：" + json.getString("id"));

            JSONObject wJson = new JSONObject();
            wJson.put("id",role.getId());
            wJson.put("name",role.getName());
            workList.add(wJson);
        });
        MaintenanceOrder maintenanceOrder = maintenanceOrderRepository.findOne(id);
        maintenanceOrder.setWorker1(workList.toString());
        maintenanceOrder.setWorker1Show(maintenanceOrder.changeWorkerToWorkerShow(maintenanceOrder.getWorker1()));
        if(maintenanceOrder.getFinishDate() != null && !Objects.equals("finish",maintenanceOrder.getState())) throw new RuntimeException("工单是完成状态，但是state是create");
        maintenanceOrderRepository.saveAndFlush(maintenanceOrder);
        return MapUtil.mapper("ID",id,"workList",maintenanceOrder.getWorker1());
    }

    public Map findContractTax(SimpleRequest re){
        JSONObject jo = re.getJO();
        String partnerId = jo.getString("partnerId");
        String productId = jo.getString("productId");
        Product product = SpringManager.getBean(ProductRepository.class).findOne(productId);
        PartyRole partner = partyRoleRepository.findOne(partnerId);
        JSONObject t11 = new ConditionBuilder.Builder("T11")
                .setBrandId(product.getBrand().getId())
                .setClassifyId(product.getClassify().getId())
                .setSupplierId(partner.getId()).build().execCondition().getResultJson();
        if (t11.getBigDecimal("P101")==null)return MapUtil.mapper("taxRate",0 );

        return MapUtil.mapper("taxRate",t11.getBigDecimal("P101").doubleValue()/100 );
    }


    private String getLoggerRemark(JSONObject jo){
        return jo.containsKey("loggerRemark") ? jo.getString("loggerRemark") : "";
    }

    private boolean isCreateLogger(JSONObject jo){
        // 只有createLogger为false才返回false，其他情况都返回true
        if (!jo.containsKey("createLogger")) return true;
        Boolean isCreateLogger = jo.getBoolean("createLogger");
        if (!Objects.isNull(isCreateLogger) && isCreateLogger == false) return false;
        return true;
    }

    /**
     * 根据供应商与合同类型判断获取税率 （只有合同为采购合同时才有税率）
     * @param supplier 供应商
     * @param contract 合同
     * @return
     */
    public double getTax(Party supplier,Contract contract){
        if ("Contract.contractType.supplier".equals(contract.getContractType().getId())){
            return supplier.getCorporate().getTax().getAmt() / 100;
        } else {
            return 0;
        }
    }

    /**
     * 记录reWriteBackData方案的入参
     * @param maintenanceOrder
     * @param type
     */
    private void reWriteBackDataLogger(MaintenanceOrder maintenanceOrder,String type){
        try {
            Document document = new Document();
            document.put("request", MapUtil.mapper("maintenanceOrder",MapUtil.mapped(maintenanceOrder),"type",type));
            document.put("id",maintenanceOrder.getId());
            document.put("date",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            SpringManager.getBean(MongoTemplate.class).getCollection("reWriteBackDataLogger").insertOne(document);
        } catch (Exception e) {
            return;
        }
    }

    private void toOutErpLogger(ServicePlan servicePlan, PartyRole person, JSONObject jo) {
        if (!isCreateLogger(jo)) return;
        User user =userRepository.findAll(JpaDsl.toCriteriaByEq("person.id",person.getId())).stream().findFirst().orElse(null);
        servicePlanceService.addServicePlanLogger(servicePlan,"转外协", "",user.getId());
    }

    /**
     * 施工提示
     * @param request
     * @return
     */
    private Map constructionTips(SimpleRequest request){
        JSONObject jo = request.getJO();
        String id = jo.getString("source");
        if (!jo.containsKey("fittings")) return MapUtil.mapper("tipsMsg","");
        List fittingIds = jo.getJSONArray("fittings").stream().map(item -> ((JSONObject) item).getString("id")).collect(Collectors.toList());
        if (fittingIds.isEmpty()) return MapUtil.mapper("tipsMsg","");
        MaintenanceOrder source = maintenanceOrderRepository.findOne(id);  // 工时工单
        List<ServicePlanItem> fittings = servicePlanItemRepository.findAll(JpaDsl.toCriteria("id", "in", fittingIds)); // 配件明细
        String sourceServicePlanId = source.getServicePlanItem().getServicePlan().getId();
        boolean isTips = false;
        for (ServicePlanItem fitting : fittings) {
            String fittingServicePlanId = fitting.getServicePlan().getId();
            if (!sourceServicePlanId.equals(fittingServicePlanId)){
                isTips = true;
                break;
            }
        }
        if (isTips){
            return MapUtil.mapper("tipsMsg","存在配件与当前工时方案不匹配，需勾选的方案全部结算后才可核算提成。");
        }else{
            return MapUtil.mapper("tipsMsg","");
        }
    }
}
